[MLton] Exporting closures to C code

Florian Weimer fw@deneb.enyo.de
Sun, 25 Sep 2005 22:31:36 +0200


* Matthew Fluet:

>> Most C libraries which use callback functions provide some means to
>> pass a user-supplied pointer to the callback function.  This could be
>> used to invoke MLton functions from C code (passing the closure
>> explicitly), even if these functions are not exported.
>>
>> How hard would that be to implement?
>
> Trivially:
>
> (* An  int -> int  function to export to C. *)
> val () = _export "f_callback": int -> int; f
>
> (* Import the address of the exported ML function. *)
> val f_addr = _address "f_callback" : MLton.Pointer.t
>
> (* A C function to register an  int -> int  callback. *)
> val reg_callback = _import "register_callback": MLton.Pointer.t -> unit;
>
> (* Pass the address of the ML function to the registration function. *)
> val () = reg_callback f_addr
>
>
> This has the very minor disadvantage of introducing "f_callback" as a 
> public exported C symbol, rather than keeping it entirely private to the 
> ML code.

But I can't use that to write a

  val register_callback : object -> (object -> int -> int) -> ()

function which registers an arbitrary object -> int -> int function
with a certain object, I think.  If I start to use it for multiple
objects, the closure address stored with f_callback is overwritten,
and only the last registered callback is ever called.

Or is this analysis incorrect?