Version française
Home     About     Download     Resources     Contact us    
Browse thread
C Callback issues
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Olivier Andrieu <oandrieu@n...>
Subject: Re: [Caml-list] C Callback issues
 Thomas Fischbacher [Wednesday 23 November 2005] :
 >
 > 
 > Hello all,
 > 
 > suppose I have a C library which provides functionality via registering C 
 > callbacks that take a closure parameter. For the sake of this example,
 > let's say via set_foo_callback(void (*f)(void *),void *closure_param).
 > 
 > Now, if I want to lift this to the OCaml level by writing a C 
 > callback-wrapper which will use the closure arg to pass the OCaml 
 > function to be called, I encounter a slight problem:
 > 
 > Callbacks have to be "announced globally" to C by means of 
 > Callback.register.

Well, no, not really. Bindings with callbacks usually don't use this
registering mechanism. You can do something like this:

,----
| static void foo_wrapper (void *);
| 
| CAMLprim value
| ml_set_foo_callback (value f)
| {
|   static value closure;
|   if (closure == 0)
|       caml_register_global_root (&closure);
|   closure = f;
|   set_foo_callback (foo_wrapper, &closure);
|   return Val_unit;
| }
| 
| static void
| foo_wrapper (void *data)
| {
|   value *closure = data;
|   value res;
|   res = caml_callback_exn (*closure, Val_unit);
|   /* optionally : */
|    *  if (Is_exception_val (res))
|    *    do_something()
|    */
| }
`----

and on the caml side, it's simply:

  external set_foo_callback : (unit -> unit) -> unit = "ml_set_foo_callback"

You can also malloc the space for the C parameter:

  value *closure;
  closure = caml_stat_alloc (sizeof *closure);
  *closure = f;
  caml_register_global_root (closure);
  ...

which you'd need to free at some point:

  caml_unregister_global_root (closure);
  caml_stat_free (closure);

It depends on how exactly the C API works (e.g. wether specifying NULL
as the function callback is used the unregister the callback).

-- 
   Olivier