我试图让这个Ruby内联C代码http://pastie.org/2825882工作.代码在vanilla C中运行,但在这里我得到错误和警告.是什么导致这个错误?
./backtrack_inline.rb:67: error: lvalue required as unary '&' operand
Run Code Online (Sandbox Code Playgroud)
另外,为什么我会收到以下错误?
./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'
Run Code Online (Sandbox Code Playgroud)
检查生成的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
Run Code Online (Sandbox Code Playgroud)
从这开始:
./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'
Run Code Online (Sandbox Code Playgroud)
如果查看生成的代码,backtrack则在第29行定义该函数:
static VALUE backtrack(VALUE self, VALUE _ss, VALUE _s, VALUE _p, VALUE _mm, VALUE _ins, VALUE _del) { ... }
Run Code Online (Sandbox Code Playgroud)
它有七个参数,原来的六个,加上VALUE self因为它已被转换为Scan类的方法.
第67行对此函数的调用如下所示:
end = backtrack(ss, s, p, mm, ins, del);
Run Code Online (Sandbox Code Playgroud)
它只有六个参数.RubyInline不会将此转换为对对象上的方法的调用,它只是逐字复制它.这也是关于makes integer from pointer without a cast来自的警告:函数定义已被转换为VALUEs,但是您使用原始类型进行调用.
错误消息表明错误来自第73行,backtrack_inline.rb因为生成的代码的第54行上的指令:
# line 61 "./backtrack_inline.rb"
Run Code Online (Sandbox Code Playgroud)
这基本上告诉编译器"重置"其行和文件值的错误,并将下一行(55)视为文件中的第61行./backtrack_inline.rb.实际行是在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
Run Code Online (Sandbox Code Playgroud)
这实际上是指生成的代码的第61行,它看起来像:
char* s = StringValuePtr(rb_iv_get(self, "@seq"));
Run Code Online (Sandbox Code Playgroud)
StringValuePtr是一个宏,定义为:
#define StringValue(v) rb_string_value(&(v))
Run Code Online (Sandbox Code Playgroud)
这就是&中lvalue required as unary '&' operand得来的.您需要将局部变量添加为左值:
VALUE seq = rb_iv_get(self, "@seq");
char* s = StringValuePtr(seq);
Run Code Online (Sandbox Code Playgroud)
在我的情况下(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
Run Code Online (Sandbox Code Playgroud)
这实际上是指ruby文件的第46行:
return (s - ss) - 1;
Run Code Online (Sandbox Code Playgroud)
s并且ss是char *64位指针(在这台机器上),函数的返回类型是int- 32位.添加显式强制转换修复此问题:
return (int)((s - ss) - 1);
Run Code Online (Sandbox Code Playgroud)
它现在运行得很干净:
ruby-inline $ ruby backtrack_inline.rb
14
ruby-inline $
Run Code Online (Sandbox Code Playgroud)
(我希望14是正确答案!)
这是带有这些更改的脚本版本.
| 归档时间: |
|
| 查看次数: |
603 次 |
| 最近记录: |