如何在ruby中保护一切
我想从我自己的C代码中调用ruby代码。如果引发异常,我必须保护我调用的ruby代码。rb_protect如下所示:如何在ruby中保护一切,ruby,ruby-c-extension,Ruby,Ruby C Extension,我想从我自己的C代码中调用ruby代码。如果引发异常,我必须保护我调用的ruby代码。rb_protect如下所示: VALUE rb_protect(VALUE (* proc) (VALUE), VALUE data, int * state) #define MAX_ARGS 16 struct my_callback_stuff { VALUE obj; ID method_id; int nargs; VALUE args[MAX_ARGS]; }; VALUE m
VALUE rb_protect(VALUE (* proc) (VALUE), VALUE data, int * state)
#define MAX_ARGS 16
struct my_callback_stuff {
VALUE obj;
ID method_id;
int nargs;
VALUE args[MAX_ARGS];
};
VALUE my_callback_dispatch(VALUE rdata)
{
struct my_callback_stuff* data = (struct my_callback_stuff*) rdata;
return rb_funcall2(data->obj, data->method_id, data->nargs, data->args);
}
... in some other function ...
{
/* need to call Ruby */
struct my_callback_stuff stuff;
stuff.obj = the_object_to_call;
stuff.method_id = rb_intern("the_method_id");
stuff.nargs = 3;
stuff.args[0] = INT2FIX(1);
stuff.args[1] = INT2FIX(2);
stuff.args[2] = INT2FIX(3);
int state = 0;
VALUE ret = rb_protect(my_callback_dispatch, (VALUE)(&stuff), &state);
if (state) {
/* ... error processing happens here ... */
}
}
因此,proc
必须是一个接受VALUE
参数并返回VALUE
的函数。我必须调用很多函数,但这些函数不是那样工作的。我如何rb\u保护他们不引发异常
我曾想过使用Data\u Make\u Struct
将所有内容封装到一个ruby对象中,并对其调用方法<代码>数据制作结构本身可能引发异常。如何rb\u-protect
Data\u-Make\u-Struct
?要以灵活的方式使用rb\u-protect
(例如,使用任意数量的参数调用Ruby函数),请将一个小的分派函数传递给rb\u-protect
。Ruby要求sizeof(VALUE)==sizeof(void*)
,并且rb\u protect
盲目地将值
类型的数据传递给分派函数,而不检查或修改它。这意味着您可以将任何需要的数据传递给dispatch函数,让它解压缩数据并调用适当的Ruby方法
例如,要rb\u-protect
调用Ruby方法,可以使用如下方法:
VALUE rb_protect(VALUE (* proc) (VALUE), VALUE data, int * state)
#define MAX_ARGS 16
struct my_callback_stuff {
VALUE obj;
ID method_id;
int nargs;
VALUE args[MAX_ARGS];
};
VALUE my_callback_dispatch(VALUE rdata)
{
struct my_callback_stuff* data = (struct my_callback_stuff*) rdata;
return rb_funcall2(data->obj, data->method_id, data->nargs, data->args);
}
... in some other function ...
{
/* need to call Ruby */
struct my_callback_stuff stuff;
stuff.obj = the_object_to_call;
stuff.method_id = rb_intern("the_method_id");
stuff.nargs = 3;
stuff.args[0] = INT2FIX(1);
stuff.args[1] = INT2FIX(2);
stuff.args[2] = INT2FIX(3);
int state = 0;
VALUE ret = rb_protect(my_callback_dispatch, (VALUE)(&stuff), &state);
if (state) {
/* ... error processing happens here ... */
}
}
另外,请记住,rb_rescue
或rb_sure
可能是解决某些问题的更好方法