嵌入 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()
之外,则它在每个红宝石VM 的“顶级”加入到隐式的,主被摄体的eigenclass
在红宝石,这个对象是作为顶层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;
在您的代码的某些部分创建呼叫Ruby对象的功能
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。
另一个有趣的是知道回调的参数,一种方法是以下
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