3

我正在尝试使用带有 Ruby 的内联 C 重写一个高度递归的函数。该函数接受未定义数量的参数,即在 Ruby 中它看起来像这样:

    def each_entity(*types)
      # Do something and recurse.
    end

我正在尝试使用以下代码在 inline C 中模仿这一点:

    VALUE each_entity_c(int argc, VALUE *argv)
    {
      // ...
    }

但这会产生编译错误:

inline.rb:486:in `ruby2c': Unknown type "VALUE *" (ArgumentError)

这是在 C 中完成此任务的正确方法吗?如果是这样,什么可能导致此错误?如果没有,它是如何完成的?

4

2 回答 2

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 将重写函数,使其接受 RubyVALUE类型作为参数,并添加代码以将这些转换为原始的 c 类型。您正在编写已经需要VALUE参数的代码,因此不希望完成此转换,因此您需要使用c_raw.

于 2012-01-31T17:39:50.347 回答
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 数组。

于 2012-01-31T08:34:13.933 回答