[MLton] Documentation on _export
Matthew Fluet
fluet@cs.cornell.edu
Fri, 23 Sep 2005 09:01:36 -0400 (EDT)
> In the process of writing documentation on the mzscheme<->mlton FFI,
> I came across:
>
> Export
>
> _export "C function name" attr... : cFuncTy -> unit;
>
> Denotes a function that must be applied to a SML function f and
> arranges for the exported C function to call the SML function.
>
> at <http://mlton.org/ForeignFunctionInterfaceSyntax>.
>
> This suggests that the export happens when the denoted function
> is called, in other words that the export happends at runtime.
> That can't be right? What would an improved wording look like?
I think the wording is correct. _export "foo" ensures that there is a
symbol "foo" which may be called as a C function. However, calling the
exported function before applying the "cFuncTy -> unit" denoted function
to an SML function will result in an exception at runtime claiming that
the exported function hasn't yet been initialized.
To put it another way: If your source program starts like:
...
val () = (_export "foo": (unit -> unit) -> unit) f
...
then it is transformed to something like:
val fooStub : (unit -> unit) option ref = NONE
...
val () = fooStub := SOME f
...
Hence, it is illegal to call "foo" before the stub is initialized with an
actual function.
Note, you cannot transform it to something like:
val fooStub : (unit -> unit) = f
...
val () = ()
...
since f is not in scope at the beginning of the program.
Now, in most well-structured programs, this distinction isn't likely to
cause problems. All of the _export's appear as top-level effects which
happen at the very beginning of the program before you call a Main.main
like function. So, by the time the "real" program starts, all the exports
are initialized.