3

RubyでインラインCを使って再帰性の高い関数を書き直そうとしています。この関数は未定義の数の引数を受け入れます。つまり、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でこれを達成する正しい方法ですか? もしそうなら、このエラーの原因は何ですか? そうでない場合、それはどのように行われますか?

4

2 に答える 2

1

メソッドを定義するときは、を使用する代わりに、 (または)builder.cを試してください。argsリストの最後に追加することもできますが、私のテストでは、このリストの有無にかかわらず機能するようです。安全のために、アリティを明示的に指定することも価値があるかもしれません。builder.c_rawbuilder.c_raw_singletonVALUE self

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 に答える