Использование rb_define_singleton_method в c (или c ++)

Мне очень сложно понять, почему мои вызовы rb_define_singleton и rb_define_method ломаются, когда я запускаю команду rake compile.

Во-первых, одна из проблем может заключаться в том, что я на самом деле не уверен, что на самом деле представляет последний целочисленный аргумент, чтобы решить, какое значение использовать, и я не смог найти документацию, объясняющую это, но я чувствую, что просто догадываюсь об этом но проблема, похоже, в третьем аргументе, поэтому меня беспокоит то, что

Во-вторых, моя сборка завершается ошибкой при вызове make:

сделать компиляцию ../../../../ext/fftw/fftw.cpp ../../../../ext/fftw/fftw.cpp: В функции 'void Init_fftw ()': ../../../../ext/fftw/fftw.cpp:64:58: ошибка: недопустимое преобразование из 'VALUE () (VALUE, VALUE) {aka long unsigned int () (long unsigned int, long unsigned int)} 'to' VALUE () (...) {aka long unsigned int () (...)} '[-fpermissive] rb_define_singleton_method ( cNMatrix, "r2c", fftw_r2c, 1); ^ В файле, включенном из /Users/private/.rvm/rubies/ruby-2.1.2/include/ruby-2.1.0/ruby/ruby.h:1694:0, из /Users/private/.rvm/rubies/ ruby-2.1.2 / include / ruby-2.1.0 / ruby.h: 33, из ../../../../ext/fftw/fftw.cpp:1: /Users/private/.rvm /rubies/ruby-2.1.2/include/ruby-2.1.0/ruby/intern.h:216:6: ошибка: инициализация аргумента 3 'void rb_define_singleton_method (VALUE, const char *, VALUE () ( ...), int) '[-fpermissive] void rb_define_singleton_method (VALUE, const char, VALUE (*) (ANYARGS), int); ^ make: * [fftw.o] Ошибка 1 грабли прерваны!

Ошибка означает, что я вообще не могу протестировать функции в Ruby, потому что мне нужно сделать это определение успешным, сначала я вырезал файл до минимума, чтобы попытаться сделать это

До сих пор я пробовал использовать разные типы, но ни один из них, похоже, не работал. Я начинаю подозревать, что неправильно настраиваю extconf с моими флагами и выбором компилятора, но я не уверен.

исходный код неисправного файла находится на github.

Любой совет приветствуется! Спасибо


person Magpie    schedule 18.07.2014    source источник


Ответы (1)


Документации для api ruby ​​C немного не хватает. Единственная «официальная» документация для этого - extension.rdoc < / а>

Ваша функция C может иметь одну из 20 сигнатур, но поскольку в C нет перегрузки и создание 20 версий всех rb_define_method вариантов добавит много повторений в интерфейс, который вы используете RUBY_METHOD_FUNC(your_function) для приведения типов указателя на функцию.

Целочисленный параметр сообщает Ruby, какую подпись вы используете:

0 до 17 означает, что ваша функция C выглядит так:

VALUE some_function(VALUE self, VALUE arg1, VALUE arg2); /* if you had passed 2 */

Целое число - это просто количество аргументов, которые принимает функция, не включая self (так что это также то же самое, что и количество аргументов, переданных в ruby ​​land).

-1 означает, что ваша функция должна иметь подпись

VALUE some_function(VALUE self, VALUE *argv, VALUE argc);

т.е. вам передается массив аргументов и количество аргументов. Это также означает, что ruby ​​позволит вызывать метод с любым количеством аргументов (т.е. сообщаемая арность будет равна -1). В этом случае часто бывает полезно rb_scan_args.

Наконец, -2 означает, что ваша функция выглядит как

VALUE some_function(VALUE self, VALUE args);

и args - массив рубинов, содержащий ваши аргументы (опять же, это позволяет вызывающей стороне передавать любое количество аргументов).

К сожалению, приведение типов означает, что если вы сделаете это неправильно, ваш код просто взорвется каким-то неопределенным образом во время выполнения, а не будет ошибкой времени компиляции.

person Frederick Cheung    schedule 19.07.2014
comment
RUBY_METHOD_FUNC (some_function) выполняет это точное преобразование типов за вас. Вы можете принять любой ответ, какой хотите - person Frederick Cheung; 19.07.2014
comment
Я думаю, хорошо иметь и то, и другое. Я попробую это как следует и посмотрю, понимаю ли я, как это работает. - person Magpie; 20.07.2014