Rubyを埋め込み、Cから関数を呼び出す
-
25-09-2019 - |
質問
c から Ruby コードを呼び出すアプリを作成しています。私は少し問題を抱えているので、誰かが私に儀式の方向を教えてくれないかと思いました。
現在Cに入れています。
#include ruby.h
main()
{
ruby_init();
rb_require("myRubyFile");
rb_funcall(rb_module_new(), rb_intern("RubyFunction"), 0, NULL);
}
私の Ruby ファイルは、C ファイルと同じディレクトリにあり、myRubyFile.rb という名前で、関数 RubyFunction() の定義が含まれています。
これは私が実際にやりたいことを切り詰めたもので、他の人が読みやすいようにしただけです。これが c ファイルから Ruby コードを呼び出す正しい方法であるかどうかについてフィードバックが必要です。
よろしく
解決
答え:
extern VALUE rb_vm_top_self(void); /* Assumes 1.9. Under 1.8, use the global
* VALUE ruby_top_self
*/
...
rb_funcall(rb_vm_top_self(), /* irb> RubyFunction() */
rb_intern("RubyFunction"), /* irb> self.RubyFunction() # same thing */
0,
NULL);
な答え:
最初の引数 rb_funcall
は 受信機 の方法。
とい def
ined RubyFunction()
外の明示的なクラスやモジュールの文脈で、その後追加されますのeigenclassの暗黙, 主なオブジェクトの"トップレベル"の毎ruby vm.
Rubyで、このオブジェクトにアクセスしてトップレベルの self
:
$ cat myRubyFile.rb
# file: myRubyFile.rb
def foo
puts "foo"
end
$ irb
irb> require "myRubyFile"
=> true
irb> foo
foo
=> nil
irb> self.foo() # same thing, more explicit
foo
=> nil
irb> self
=> main
C下1.9アクセス可能ですと答させていただきます。
他のヒント
私は、次のアプローチを使用してみます:
共有データへの基本的な構造体
typedef struct ruby_shared_data {
VALUE obj;
ID method_id;
int nargs;
VALUE args[4];
} ruby_shared_data;
あなたのコードの一部にコールルビー・オブジェクトの関数を作成します。
static VALUE ruby_callback(VALUE ptr) {
ruby_shared_data *data = (ruby_shared_data*)ptr;
return rb_funcall2(data->obj,data->method_id,data->nargs,data->args);
}
あなたのコードの一部には...
ruby_shared_data rbdata;
rbdata.obj = obj;
rbdata.method_id = rb_intern("mycallback");
rbdata.nargs = 1;
rbdata.args[0] = rb_str_new2("im a parameter");
int error = 0;
VALUE result = rb_protect(ruby_callback,(VALUE)&rbdata,&error);
if (error)
throw "Ruby exception on callback";
rb_protectでrb_funcallラップすることは常に良い考えです。
もう一つの興味深い点は、コールバックのパラメータを知っている、1つのアプローチは以下の通りです。
ruby_shared_data rbdata;
rbdata.obj = callback;
rbdata.method_id = rb_intern("arity");
rbdata.nargs = 0;
int error = 0;
VALUE result = rb_protect(ruby_callback,(VALUE)&rbdata,&error);
if (error)
throw "Ruby exception on callback";
narguments = NUM2INT(result);
所属していません StackOverflow