## MLton 20241230+git20251029+dfsg-5

# CallingFromCToSML

MLton’s ForeignFunctionInterface allows programs to export SML functions to be called from C. Suppose you would like export from SML a function of type `real * char -> int` as the C function `foo`. MLton extends the syntax of SML to allow expressions like the following:

    _export "foo": (real * char -> int) -> unit;

The above expression exports a C function named `foo`, with prototype

    Int32 foo (Real64 x0, Char x1);

The `_export` expression denotes a function of type `(real * char -> int) -> unit` that when called with a function `f`, arranges for the exported `foo` function to call `f` when `foo` is called. So, for example, the following exports and defines `foo`.

    val e = _export "foo": (real * char -> int) -> unit;
    val _ = e (fn (x, c) => 13 + Real.floor x + Char.ord c)

The general form of an `_export` expression is

    _export "C function name" attr... : cFuncTy -> unit;

The type and the semicolon are not optional. As with `_import`, a sequence of attributes may follow the function name.

MLton’s `-export-header` option generates a C header file with prototypes for all of the functions exported from SML. Include this header file in your C files to type check calls to functions exported from SML. This header file includes `typedef`s for the types that can be passed between SML and C.

## Example

Suppose that `export.sml` is

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

Note that the the `reentrant` attribute is used for `_import`-ing the C functions that will call the `_export`-ed SML functions.

Create the header file with `-export-header`.

    % mlton -default-ann 'allowFFI true'    \
            -export-header export.h         \
            -stop tc                        \
            export.sml

`export.h` now contains the following C prototypes.

    Int8 f (Int32 x0, Real64 x1, Int8 x2);
    Pointer f2 (Word8 x0);
    void f3 ();
    void f4 (Int32 x0);
    extern Int32 zzz;

Use `export.h` in a C program, `ffi-export.c`, as follows.

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

Compile `ffi-export.c` and `export.sml`.

    % gcc -c ffi-export.c
    % mlton -default-ann 'allowFFI true' \
             export.sml ffi-export.o

Finally, run `export`.

    % ./export
    g starting
    ...
    g4 (0)
    success

## Download

- `export.sml`

- `ffi-export.c`