[MLton] Callback to function pointer?

Stephen Weeks MLton@mlton.org
Tue, 12 Jul 2005 12:59:59 -0700


> Now, if you don't want to leave SML to get the address of an "_export"ed 
> function, then that is currently supported, using an (as of yet 
> undocumented) feature of MLton FFI.  Essentially,
> 
>   _import # "name": MLton.Pointer.t;

I wonder if "&" would be better than "#" here?

  _import & "name": MLton.Pointer.t;

> Hence, we can write your example as follows:
> 
> fun clicker1 () = print "clicked callback 1!\n"
> val () = (_export "clicker1" : unit -> unit;) clicker1
> val clicker1Ptr = _import # "clicker1": MLton.Pointer.t
> fun clicker2 () = print "clicked callback 2!\n"
> val () = (_export "clicker2" : unit -> unit;) clicker2
> val clicker2Ptr = _import # "clicker2": MLton.Pointer.t
> 
> val gui_clicked = _import "gui_clicked": MLton.Pointer.t -> unit;
> fun setupclick fPtr = gui_clicked fPtr
> 
> val () = setupclick clicker1Ptr
> val () = setupclick clicker2Ptr

I don't see how you could do much better than this (other than minor
syntactic improvements).  What Wesley wants is impossible without
run-time code generation as far as I can see.  The problem is that C
function pointers don't have any hooks to store a closure record.  If
one wants to pass differently behaving functions via C function
pointers, one must use different addresses.  The above approach does
this by generating the addresses at compile time via _export.

On the other hand, Wesley, if the C code that you're trying to FFI to
has a hook in addition to the C function pointer, then perhaps
something can be done better than a global table?