[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ 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