私は次のアプローチを使おうとしています。
データを共有するための基本的な構造
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_funcallをrb_protectでラップすることは常に良い考えです。
もう1つの興味深いことは、コールバックのパラメーターを知ることです。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);