caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Olivier Andrieu <oandrieu@nerim.net>
To: Thomas Fischbacher <Thomas.Fischbacher@Physik.Uni-Muenchen.DE>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] C Callback issues
Date: Wed, 23 Nov 2005 14:40:06 +0100	[thread overview]
Message-ID: <17284.28982.834548.164979@karryall.dnsalias.org> (raw)
In-Reply-To: <Pine.LNX.4.61.0511231319580.19523@eiger.cip.physik.uni-muenchen.de>

 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


  reply	other threads:[~2005-11-23 13:40 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-11-23 12:59 Thomas Fischbacher
2005-11-23 13:40 ` Olivier Andrieu [this message]
2005-11-23 14:11   ` [Caml-list] " Thomas Fischbacher
2005-11-23 13:41 ` Alain Frisch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=17284.28982.834548.164979@karryall.dnsalias.org \
    --to=oandrieu@nerim.net \
    --cc=Thomas.Fischbacher@Physik.Uni-Muenchen.DE \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).