Компиляция кода Ruby Inline C - устранение ошибок - PullRequest
6 голосов
/ 07 ноября 2011

Я пытаюсь заставить работать этот код C на Ruby http://pastie.org/2825882. Код работает в vanilla C, но здесь я получаю ошибки и предупреждения. Что вызывает эту ошибку?

./backtrack_inline.rb:67: error: lvalue required as unary '&' operand

Кроме того, почему я получаю следующую ошибку?

./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'

Проверка получающегося кода C (http://pastie.org/2826036) Я не вижу ничего плохого в аргументах. Но я также получаю следующие предупреждения:

./backtrack_inline.rb:73: warning: passing argument 1 of 'backtrack' makes integer from pointer without a cast
./backtrack_inline.rb:73: warning: passing argument 2 of 'backtrack' makes integer from pointer without a cast
./backtrack_inline.rb:73: warning: passing argument 3 of 'backtrack' makes integer from pointer without a cast

Ответы [ 3 ]

5 голосов
/ 10 ноября 2011

Начиная с этого:

./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'

Если вы посмотрите на сгенерированный код, функция backtrack определена в строке 29:

static VALUE backtrack(VALUE self, VALUE _ss, VALUE _s, VALUE _p, VALUE _mm, VALUE _ins, VALUE _del) { ... }

У него есть семь аргументов, исходные шесть, плюс VALUE self, поскольку он был преобразован в метод класса Scan.

Вызов этой функции в строке 67 выглядит следующим образом:

end = backtrack(ss, s, p, mm, ins, del);

У него только шесть аргументов. RubyInline не преобразует это в вызов метода объекта, а просто копирует его дословно. Отсюда и предупреждения о makes integer from pointer without a cast: определение функции было преобразовано в VALUE с, но вы вызываете с исходными типами.

Сообщение об ошибке говорит, что ошибка от строки 73 в backtrack_inline.rb из-за директивы в строке 54 сгенерированного кода:

# line 61 "./backtrack_inline.rb"

, который в основном говорит компилятору "сбрасывать" свои строки и значения файла для ошибок и обрабатывать следующую строку (55) как строку 61 в файле ./backtrack_inline.rb. Фактическая строка - 67, 12 перед 55, но компилятор сообщает, что это 73, 12 перед 61 (значение, в которое он был сброшен) и из другого файла. Этот метод не работает в этом случае, так как он не учитывает дополнительные строки, добавленные RubyInline. Фактическая строка в источнике - 69.

Простым исправлением для этого является изменение определения функции backtrack, чтобы она была просто функцией C, а не добавление ее в качестве метода для объекта. Измените builder.c на builder.prefix (в строке 38 вашего файла Ruby). Это не сработает, если вы хотите, чтобы backtrack был доступен в качестве метода для объекта в Ruby. Если это так, то вам может потребоваться создать другую функцию, которая будет методом, который затем обернет «реальную» функцию возврата.

Далее, глядя на

./backtrack_inline.rb:67: error: lvalue required as unary '&' operand

На самом деле это относится к строке 61 сгенерированного кода, которая выглядит следующим образом:

char* s = StringValuePtr(rb_iv_get(self, "@seq"));

StringValuePtr - это макрос , который определяется как :

#define StringValue(v) rb_string_value(&(v))

Отсюда и & в lvalue required as unary '&' operand. Вам нужно добавить локальную переменную, которая будет lvalue:

VALUE seq = rb_iv_get(self, "@seq");
char* s = StringValuePtr(seq);

В моем случае (Mac OS X Snow Leopard, Ruby 1.9.3-p0, RubyInline 3.11.0) эти два изменения сделали скрипт запущенным без ошибок, но выдало предупреждение:

backtrack_inline.rb:47: warning: implicit conversion shortens 64-bit value into a 32-bit value

На самом деле это относится к строке 46 файла ruby:

return (s - ss) - 1;

s и ss равны char *, т. Е. 64-битные указатели (на этом аппарате), а тип возвращаемого значения функции - int - 32 бита. Добавление явного приведения исправило это:

return (int)((s - ss) - 1);

Теперь он работает без ошибок:

ruby-inline $ ruby backtrack_inline.rb 
14
ruby-inline $ 

(Надеюсь, 14 правильный ответ!)

Вот версия скрипта с этими изменениями .

1 голос
/ 17 ноября 2011

ОК, на Ruby Forum также был дан ответ:

http://www.ruby -forum.com / тема / 2959614

0 голосов
/ 09 ноября 2011

Хорошо ... немного подумал об этом.

Вы вызываете переменную end.Хотя это не зарезервированное слово в C - и ruby ​​не должен на это смотреть ... возможно, ruby ​​запутывается?

Я бы предложил вам попробовать переименовать его на всякий случай.Стоит даже попытаться исключить это.

...