Summary: callbacks (called in C embedding or extending Ruby)

  • Thread starter Basile STARYNKEVITCH
  • Start date
B

Basile STARYNKEVITCH

A summary for people embedding Ruby

To answer to my previous questions (thanks to hint by Guy Decoux) here
is the way to register a callback (ie how to call a ruby routine from
C)

declare a static value (to contain the called proc)

/*in C */
static VALUE hook_block;

don't forget to register in to the GC with

/* in C, inside your initialisation */
rb_global_variable (&hook_block);

to be able to register the hook using

# in ruby
register_hook do |arg1|
#do something with arg1
end

the C code for register_hook should be like

/*C code for register_hook*/
static VALUE my_register_hook(VALUE self) {
if (rb_block_given_p ()) {
/* a block was given - remember it */
hook_block = rb_block_proc ();
} else {
/* no block given, clear the hook */
hook_block = Qfalse;
}
}

and the initialisation should contain
/* in C, inside your initialisation */
rb_define_module_function (your_module, "register_hook",
my_register_hook, 0);

to call the hook from a C function you first test that the hook is a
procedure
/* in C, checking the hook */
if (!rb_obj_is_kind_of (hook_block, rb_cProc))
return;

you might also need to protect the hook call against ruby exceptions
or error, eg with

/* in C calling the hook */
VALUE arghook = somethinguseful;
VALUE argres = somethinguseful;
rb_rescue (hook_handler, arghook, hook_rescuer, argres);


where the hook_handler is something like
/* in C hook handler */
static VALUE hook_handler(VALUE arghook) {
VALUE res = 0;
VALUE tabarg[1] = { 0 };
int call_id = rb_intern ("call");
tabarg[0] = arghook;
res = rb_funcall2 (hook_block, call_id, 1, tabarg);
return res;
}

and the hook_rescuer compute result when an exception happened, eg
/* in C */
static VALUE hook_rescuer (VALUE argres) {
/* etc */
}

Even with serious help I spent more than an hour finding this out. I
suggest it should be documented somewhere!

I use this in Guis (an opensource GTK widget server) see
http://www.starynkevitch.net/Basile/guisdoc.html

--

Basile STARYNKEVITCH http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net
aliases: basile<at>tunes<dot>org = bstarynk<at>nerim<dot>net
8, rue de la Faïencerie, 92340 Bourg La Reine, France
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top