6

我试图让这个 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
4

3 回答 3

5

从此开始:

./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来源:函数定义已转换为 take VALUEs,但您使用原始类型进行调用。

错误消息说backtrack_inline.rb由于生成代码的第 54 行上的指令,错误来自第 73 行:

# line 61 "./backtrack_inline.rb"

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

一个简单的解决方法是将backtrack函数的定义更改为只是一个 C 函数,而不是将其作为方法添加到对象上。更改builder.cbuilder.prefix(在 Ruby 文件的第 38 行)。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))

这就是&in 的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 是正确的答案!)

这是具有这些更改的脚本版本

于 2011-11-09T22:47:50.003 回答
1

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

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

于 2011-11-16T20:10:55.817 回答
0

好吧...想了更多关于这个。

你正在调用一个变量结束。虽然这不是 C 中的保留字 - 并且 ruby​​ 不应该查看它......也许 ruby​​ 变得困惑?

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

于 2011-11-09T18:15:38.840 回答