## MLton 20241230+git20251029+dfsg-5

# CallingFromSMLToCFunctionPointer

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.

    Unresolved directive in CallingFromSMLToCFunctionPointer.adoc - include::https://raw.github.com/MLton/mlton/master/doc/examples/ffi/iimport.sml[indent=0]

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`.

## Download

- `iimport.sml`