在 Ruby/Inline C 中接受未定义数量的参数

发布于 2025-01-01 05:52:39 字数 456 浏览 1 评论 0原文

我正在尝试使用内联 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 中完成此操作的正确方法吗?如果是这样,什么可能导致此错误?如果没有,是怎么做到的?

I am trying to rewrite a highly recursive function using inline C with Ruby. The function accepts an undefined number of arguments, i.e. it would look like this in Ruby:

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

I am trying to mimick this in inline C using the following code:

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

But this yields the compile error:

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

Is this the correct way to accomplish this in C? If so, what could have caused this error? If not, how is it done?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海的爱人是光 2025-01-08 05:52:39

而不是使用 builder.c ,尝试 builder.c_raw(或builder.c_raw_singleton)定义你的方法时。您可能想将 VALUE self 添加到 args 列表的末尾,但在我的测试中,无论有没有,它似乎都可以工作。为了安全起见,也可能值得显式指定元数:

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

Instead of using builder.c, try builder.c_raw (or builder.c_raw_singleton) when defining your methods. You might want to add VALUE self to the end of the args list, but it seems to work with or without in my tests. It might also be worth explicitly specifying the arity, just to be safe:

inline do |builder|

  builder.c_raw <<-EOS, :arity => -1
    VALUE each_entity_c(int argc, VALUE *argv, VALUE self)
    {
      // ...
    }
  EOS
end

Using builder.c, Ruby Inline will rewrite the function so that it accepts Ruby VALUE types as parameters, and add code to convert these to the c types in your original. You're writing code that already expects VALUE arguments so don't want this conversion to be done, so you need to use c_raw.

泪意 2025-01-08 05:52:39

如果我没记错的话,您想要的是:

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 数组。

If I'm not mistaken, you want to you this:

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);

The C function is given a Ruby array with all arguments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文