Hi, for some C bindings I’m trying to registers callbacks with both user provided callbacks and user provided data. Something like this:
button#connect_clicked print_endline "Hello there"
The problem. It works when the data is an integer, or a string or a record or a function. It does not work when the data is an object.
Here is the C function I use to register the roots for further use:
gpointer make_closure(value callback, value data)
{
struct callback_closure *closure = g_malloc(sizeof(struct callback_closure));
caml_register_generational_global_root(&closure->callback);
closure->callback = callback;
if (Is_block(data))
{
caml_register_generational_global_root(&closure->data);
}
closure->data = data;
return closure;
}
In the callback I unpack the closure and use both callback
and data
. And there seem to be a problem with objects. Adding some debug
debug "0: area" area;
print_endline @@ "area oid " ^ string_of_int (Oo.id area) ;
prints I see the following (outside and inside the callback)
0: area: <248> 0x7f5a41bd9740
area oid 10
...
1: area: <0> 0x7f5a41bd9740
area oid 10
Where <number>
is Tag_val
of OCaml value.
Any suggestions?
PS. It happens reliably if I call Gc.compact ()
after registering the callback. So it looks like the GC is changing the header (field 0) of the object value.