[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?