我正在尝试使用内联C和Ruby重写一个高度递归的函数。该函数接受一个未定义数量的参数,即它在Ruby中看起来像这样:
def each_entity(*types)
# Do something and recurse.
end
我正在尝试使用以下代码在内联C中模仿它:
VALUE each_entity_c(int argc, VALUE *argv)
{
// ...
}
但这会产生编译错误:
inline.rb:486:in `ruby2c': Unknown type "VALUE *" (ArgumentError)
这是在C中完成此操作的正确方法吗?如果是这样,可能导致此错误的原因是什么?如果没有,它是如何完成的?
答案 0 :(得分:1)
在定义方法时,请尝试builder.c
(或builder.c_raw
),而不是使用builder.c_raw_singleton
。您可能希望将VALUE self
添加到args列表的末尾,但它似乎可以在我的测试中使用或不使用。为了安全起见,也可能值得明确指定arity:
inline do |builder|
builder.c_raw <<-EOS, :arity => -1
VALUE each_entity_c(int argc, VALUE *argv, VALUE self)
{
// ...
}
EOS
end
使用builder.c
,Ruby Inline将重写该函数,使其接受Ruby VALUE
类型作为参数,并添加代码以将这些类型转换为原始类型中的c类型。您正在编写已经需要VALUE
个参数的代码,因此不希望完成此转换,因此您需要使用c_raw
。
答案 1 :(得分:0)
如果我没弄错的话,你想要这个:
VALUE each_entity_c(VALUE self, VALUE args)
{
// args is a Ruby array with all arguments
}
rb_define_method(class, "MyClass", each_entity_c, -2);
给C函数一个带有所有参数的Ruby数组。