编译Ruby Inline C代码 - 解决错误

时间:2011-11-07 16:14:40

标签: ruby inline-code

我试图让这个Ruby内联C代码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 个答案:

答案 0 :(得分:5)

从这开始:

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

如果查看生成的代码,{29}将定义backtrack函数:

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,但您使用原始类型进行调用。

错误消息显示错误来自backtrack_inline.rb中的第73行,因为生成的代码的第54行指示:

# line 61 "./backtrack_inline.rb"

基本上告诉编译器“重置”其行和文件值以查找错误,并将下一行(55)视为文件./backtrack_inline.rb中的第61行。实际行是在67之前的67,12,但是编译器将其报告为73,12先于61(它被重置为的值)和来自不同的文件。这种技术在这种情况下并不真正起作用,因为它没有考虑RubyInline添加的额外行。源中的实际行是69。

对此的一个简单修复是将backtrack函数的定义更改为C函数,而不是将其作为方法添加到对象上。将builder.c更改为builder.prefix(在Ruby文件的第38行)。如果你想让backtrack作为Ruby中对象的方法可用,这将不起作用。如果是这种情况,你可能需要创建另一个函数作为方法,然后包装“真正的”回溯函数。

接下来,看看

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

这实际上是指生成代码的第61行,如下所示:

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

StringValuePtrmacro which is defined as

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

这是&中的lvalue required as unary '&' operand来自的地方。您需要将局部变量添加为左值:

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

这实际上是指ruby文件的第46行:

return (s - ss) - 1;

ssschar *,即64位指针(在此计算机上),函数的返回类型为int - 32位。添加一个显式的强制转换修复了这个:

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

它现在运行得很干净:

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

(我希望14是正确答案!)

这是version of the script with these changes

答案 1 :(得分:1)

好的,Ruby论坛也回答了这个问题:

http://www.ruby-forum.com/topic/2959614

答案 2 :(得分:0)

好的......想一想这个。

你正在调用变量。虽然这不是C语言中的保留词 - 而且ruby不应该看它...也许红宝石会变得混乱?

为了以防万一,我建议您重新命名。值得尝试,甚至只是为了排除它。