为什么这段代码在测试时会返回错误数量的元素?它似乎是正确值的一半
我使用的是RubyInline版本3.12.2。和Ruby 1.9.3
inline do|builder|
builder.c <<-EOS
VALUE arraylength( VALUE testarr){
int arrlen = RARRAY_LEN(testarr);
return arrlen;
}
EOS
end
结果是
arraylength([1,2,3,4,5])
#=>2
我期待
arraylength([1,2,3,4,5])
#=>5
答案 0 :(得分:1)
代码的问题在于您已声明C函数返回VALUE
(用于标识Ruby对象的长指针类型),但随后返回int
。编译器可以在这里强制强制,并且RubyInline可能会抑制编译时产生的警告。
最终结果是该方法返回Ruby Object
,其object_id
等于您传入的数组的长度。对于int
的大多数小值,这只是一个映射到Fixnum
(即看起来像“错误的整数”)。
碰巧,2.object_id == 5
这就是为什么在你期望5时得到2的原因。
修复是为了确保您返回正确的类型。您可以像这样返回VALUE
:
inline do |builder|
builder.c <<-EOS
VALUE arraylength( VALUE testarr ){
int arrlen = RARRAY_LEN(testarr);
return INT2NUM( arrlen );
}
EOS
end
或者您可以直接在int
中工作,让RubyInline为您转换:
inline do |builder|
builder.c <<-EOS
int arraylength( VALUE testarr ){
int arrlen = RARRAY_LEN(testarr);
return arrlen;
}
EOS
end
我不使用RubyInline,但怀疑当RubyInline可以为您进行转换时,第二个版本会更受欢迎。但在幕后,它可能会改变代码看起来像第一个版本。