Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | CallingFromCToSML |
2 | ================= | |
3 | ||
4 | MLton's <:ForeignFunctionInterface:> allows programs to _export_ SML | |
5 | functions to be called from C. Suppose you would like export from SML | |
6 | a function of type `real * char -> int` as the C function `foo`. | |
7 | MLton extends the syntax of SML to allow expressions like the | |
8 | following: | |
9 | ---- | |
10 | _export "foo": (real * char -> int) -> unit; | |
11 | ---- | |
12 | The above expression exports a C function named `foo`, with | |
13 | prototype | |
14 | [source,c] | |
15 | ---- | |
16 | Int32 foo (Real64 x0, Char x1); | |
17 | ---- | |
18 | The `_export` expression denotes a function of type | |
19 | `(real * char -> int) -> unit` that when called with a function | |
20 | `f`, arranges for the exported `foo` function to call `f` | |
21 | when `foo` is called. So, for example, the following exports and | |
22 | defines `foo`. | |
23 | [source,sml] | |
24 | ---- | |
25 | val e = _export "foo": (real * char -> int) -> unit; | |
26 | val _ = e (fn (x, c) => 13 + Real.floor x + Char.ord c) | |
27 | ---- | |
28 | ||
29 | The general form of an `_export` expression is | |
30 | ---- | |
31 | _export "C function name" attr... : cFuncTy -> unit; | |
32 | ---- | |
33 | The type and the semicolon are not optional. As with `_import`, a | |
34 | sequence of attributes may follow the function name. | |
35 | ||
36 | MLton's `-export-header` option generates a C header file with | |
37 | prototypes for all of the functions exported from SML. Include this | |
38 | header file in your C files to type check calls to functions exported | |
39 | from SML. This header file includes ++typedef++s for the | |
40 | <:ForeignFunctionInterfaceTypes: types that can be passed between SML and C>. | |
41 | ||
42 | ||
43 | == Example == | |
44 | ||
45 | Suppose that `export.sml` is | |
46 | ||
47 | [source,sml] | |
48 | ---- | |
49 | sys::[./bin/InclGitFile.py mlton master doc/examples/ffi/export.sml] | |
50 | ---- | |
51 | ||
52 | Note that the the `reentrant` attribute is used for `_import`-ing the | |
53 | C functions that will call the `_export`-ed SML functions. | |
54 | ||
55 | Create the header file with `-export-header`. | |
56 | ---- | |
57 | % mlton -default-ann 'allowFFI true' \ | |
58 | -export-header export.h \ | |
59 | -stop tc \ | |
60 | export.sml | |
61 | ---- | |
62 | ||
63 | `export.h` now contains the following C prototypes. | |
64 | ---- | |
65 | Int8 f (Int32 x0, Real64 x1, Int8 x2); | |
66 | Pointer f2 (Word8 x0); | |
67 | void f3 (); | |
68 | void f4 (Int32 x0); | |
69 | extern Int32 zzz; | |
70 | ---- | |
71 | ||
72 | Use `export.h` in a C program, `ffi-export.c`, as follows. | |
73 | ||
74 | [source,c] | |
75 | ---- | |
76 | sys::[./bin/InclGitFile.py mlton master doc/examples/ffi/ffi-export.c] | |
77 | ---- | |
78 | ||
79 | Compile `ffi-export.c` and `export.sml`. | |
80 | ---- | |
81 | % gcc -c ffi-export.c | |
82 | % mlton -default-ann 'allowFFI true' \ | |
83 | export.sml ffi-export.o | |
84 | ---- | |
85 | ||
86 | Finally, run `export`. | |
87 | ---- | |
88 | % ./export | |
89 | g starting | |
90 | ... | |
91 | g4 (0) | |
92 | success | |
93 | ---- | |
94 | ||
95 | ||
96 | == Download == | |
97 | * <!RawGitFile(mlton,master,doc/examples/ffi/export.sml)> | |
98 | * <!RawGitFile(mlton,master,doc/examples/ffi/ffi-export.c)> |