Just as MLton can directly call C functions, it is possible to make indirect function calls; that is, function calls through a function pointer. MLton extends the syntax of SML to allow expressions like the following:
_import * : MLton.Pointer.t -> real * char -> int;
This expression denotes a function of type
MLton.Pointer.t -> real * char -> int
whose behavior is implemented by calling the C function at the address denoted by the MLton.Pointer.t argument, and supplying the C function two arguments, a double and an int. The C function pointer may be obtained, for example, by the dynamic linking loader (dlopen, dlsym, …).
The general form of an indirect _import expression is:
_import * attr... : cPtrTy -> cFuncTy;
The type and the semicolon are not optional.
Example
This example uses dlopen and friends (imported using normal _import) to dynamically load the math library (libm) and call the cos function. Suppose iimport.sml contains the following.
<!IncludeSVN(mlton/trunk/doc/examples/ffi/iimport.sml, sml)>
Compile and run iimport.sml.
% mlton -default-ann 'allowFFI true' \
-target-link-opt linux -ldl \
-target-link-opt solaris -ldl \
iimport.sml
% iimport
Math.cos(2.0) = ~0.416146836547
libm.so::cos(2.0) = ~0.416146836547
This example also shows the -target-link-opt option, which uses the switch when linking only when on the specified platform. Compile with -verbose 1 to see in more detail what’s being passed to gcc.