<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta name="robots" content="index,nofollow">



<title>CallingFromCToSML - MLton Standard ML Compiler (SML Compiler)</title>
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="all" href="common.css">
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="screen" href="screen.css">
<link rel="stylesheet" type="text/css" charset="iso-8859-1" media="print" href="print.css">


<link rel="Start" href="Home">


</head>

<body lang="en" dir="ltr">

<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-833377-1";
urchinTracker();
</script>
<table bgcolor = lightblue cellspacing = 0 style = "border: 0px;" width = 100%>
  <tr>
    <td style = "
		border: 0px;
		color: darkblue; 
		font-size: 150%;
		text-align: left;">
      <a class = mltona href="Home">MLton MLTONWIKIVERSION</a>
    <td style = "
		border: 0px;
		font-size: 150%;
		text-align: center;
		width: 50%;">
      CallingFromCToSML
    <td style = "
		border: 0px;
		text-align: right;">
      <table cellspacing = 0 style = "border: 0px">
        <tr style = "vertical-align: middle;">
      </table>
  <tr style = "background-color: white;">
    <td colspan = 3
	style = "
		border: 0px;
		font-size:70%;
		text-align: right;">
      <a href = "Home">Home</a>
      &nbsp;<a href = "Index">Index</a>
      &nbsp;
</table>
<div id="content" lang="en" dir="ltr">
MLton's <a href="ForeignFunctionInterface">ForeignFunctionInterface</a> allows programs to <em>export</em> SML functions to be called from C.  Suppose you would like export from SML a function of type  <tt>real&nbsp;*&nbsp;char&nbsp;-&gt;&nbsp;int</tt> as the C function <tt>foo</tt>.  MLton extends the syntax of SML to allow expressions like the following: 
<pre>_export "foo": (real * char -&gt; int) -&gt; unit;
</pre>The above expression exports a C function named <tt>foo</tt>, with prototype 
<pre>Int32 foo (Real64 x0, Char x1);
</pre>The <tt>_export</tt> expression denotes a function of type  <tt>(real&nbsp;*&nbsp;char&nbsp;-&gt;&nbsp;int)&nbsp;-&gt;&nbsp;unit</tt> that when called with a function <tt>f</tt>, arranges for the exported <tt>foo</tt> function to call <tt>f</tt> when <tt>foo</tt> is called.  So, for example, the following exports and defines <tt>foo</tt>. 
<pre class=code>
<B><FONT COLOR="#A020F0">val</FONT></B> e = _export <B><FONT COLOR="#BC8F8F">&quot;foo&quot;</FONT></B>: (real * char -&gt; int) -&gt; unit;
<B><FONT COLOR="#A020F0">val</FONT></B> _ = e (<B><FONT COLOR="#A020F0">fn</FONT></B> (x, c) =&gt; <B><FONT COLOR="#5F9EA0">13</FONT></B> + Real.floor x + Char.ord c)
</PRE>
<p>
 
</p>
<p>
The general form of an <tt>_export</tt> expression is 
</p>

<pre>_export "C function name" attr... : cFuncTy -&gt; unit;
</pre><p>
The type and the semicolon are not optional.  As with <tt>_import</tt>, a sequence of attributes may follow the function name. 
</p>
<p>
MLton's <tt>-export-header</tt> 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 <tt>typedef</tt>s for the <a href="ForeignFunctionInterfaceTypes"> types that can be passed between SML and C</a>. 
</p>
<h2 id="head-0f01ed56a1e32a05e5ef96e4d779f34784af9a96">Example</h2>
<p>
Suppose that <tt>export.sml</tt> is  
</p>
<p>
<pre class=code><B><FONT COLOR="#A020F0">val</FONT></B> e = _export <B><FONT COLOR="#BC8F8F">&quot;f&quot;</FONT></B>: (int * real * char -&gt; char) -&gt; unit;
<B><FONT COLOR="#A020F0">val</FONT></B> _ = e (<B><FONT COLOR="#A020F0">fn</FONT></B> (i, r, _) =&gt;
           (print (concat [<B><FONT COLOR="#BC8F8F">&quot;i = &quot;</FONT></B>, Int.toString i,
                           <B><FONT COLOR="#BC8F8F">&quot;  r = &quot;</FONT></B>, Real.toString r, <B><FONT COLOR="#BC8F8F">&quot;\n&quot;</FONT></B>])
            ; #<B><FONT COLOR="#BC8F8F">&quot;g&quot;</FONT></B>))
<B><FONT COLOR="#A020F0">val</FONT></B> g = _import <B><FONT COLOR="#BC8F8F">&quot;g&quot;</FONT></B>: unit -&gt; unit;
<B><FONT COLOR="#A020F0">val</FONT></B> _ = g ()
<B><FONT COLOR="#A020F0">val</FONT></B> _ = g ()

<B><FONT COLOR="#A020F0">val</FONT></B> e = _export <B><FONT COLOR="#BC8F8F">&quot;f2&quot;</FONT></B>: (Word8.word -&gt; word array) -&gt; unit;
<B><FONT COLOR="#A020F0">val</FONT></B> _ = e (<B><FONT COLOR="#A020F0">fn</FONT></B> w =&gt;
           Array.tabulate (<B><FONT COLOR="#5F9EA0">10</FONT></B>, <B><FONT COLOR="#A020F0">fn</FONT></B> _ =&gt; Word.fromLargeWord (Word8.toLargeWord w)))
<B><FONT COLOR="#A020F0">val</FONT></B> g2 = _import <B><FONT COLOR="#BC8F8F">&quot;g2&quot;</FONT></B>: unit -&gt; word array;
<B><FONT COLOR="#A020F0">val</FONT></B> a = g2 ()
<B><FONT COLOR="#A020F0">val</FONT></B> _ = print (concat [<B><FONT COLOR="#BC8F8F">&quot;0wx&quot;</FONT></B>, Word.toString (Array.sub (a, <B><FONT COLOR="#5F9EA0">0</FONT></B>)), <B><FONT COLOR="#BC8F8F">&quot;\n&quot;</FONT></B>])

<B><FONT COLOR="#A020F0">val</FONT></B> e = _export <B><FONT COLOR="#BC8F8F">&quot;f3&quot;</FONT></B>: (unit -&gt; unit) -&gt; unit;
<B><FONT COLOR="#A020F0">val</FONT></B> _ = e (<B><FONT COLOR="#A020F0">fn</FONT></B> () =&gt; print <B><FONT COLOR="#BC8F8F">&quot;hello\n&quot;</FONT></B>);
<B><FONT COLOR="#A020F0">val</FONT></B> g3 = _import <B><FONT COLOR="#BC8F8F">&quot;g3&quot;</FONT></B>: unit -&gt; unit;
<B><FONT COLOR="#A020F0">val</FONT></B> _ = g3 ()

<I><FONT COLOR="#B22222">(* This example demonstrates mutual recursion between C and SML. *)</FONT></I>
<B><FONT COLOR="#A020F0">val</FONT></B> e = _export <B><FONT COLOR="#BC8F8F">&quot;f4&quot;</FONT></B>: (int -&gt; unit) -&gt; unit;
<B><FONT COLOR="#A020F0">val</FONT></B> g4 = _import <B><FONT COLOR="#BC8F8F">&quot;g4&quot;</FONT></B>: int -&gt; unit;
<B><FONT COLOR="#A020F0">val</FONT></B> _ = e (<B><FONT COLOR="#A020F0">fn</FONT></B> i =&gt; <B><FONT COLOR="#A020F0">if</FONT></B> i = <B><FONT COLOR="#5F9EA0">0</FONT></B> <B><FONT COLOR="#A020F0">then</FONT></B> () <B><FONT COLOR="#A020F0">else</FONT></B> g4 (i - <B><FONT COLOR="#5F9EA0">1</FONT></B>))
<B><FONT COLOR="#A020F0">val</FONT></B> _ = g4 <B><FONT COLOR="#5F9EA0">13</FONT></B>

<B><FONT COLOR="#A020F0">val</FONT></B> (_, zzzSet) = _symbol <B><FONT COLOR="#BC8F8F">&quot;zzz&quot;</FONT></B> alloc: (unit -&gt; int) * (int -&gt; unit);
<B><FONT COLOR="#A020F0">val</FONT></B> () = zzzSet <B><FONT COLOR="#5F9EA0">42</FONT></B>
<B><FONT COLOR="#A020F0">val</FONT></B> g5 = _import <B><FONT COLOR="#BC8F8F">&quot;g5&quot;</FONT></B>: unit -&gt; unit;
<B><FONT COLOR="#A020F0">val</FONT></B> _ = g5 ()

<B><FONT COLOR="#A020F0">val</FONT></B> _ = print <B><FONT COLOR="#BC8F8F">&quot;success\n&quot;</FONT></B>

</PRE>
 
</p>
<p>
Create the header file with <tt>-export-header</tt>. 
</p>

<pre>% mlton -default-ann 'allowFFI true'    \
        -export-header export.h         \
        -stop tc                        \
        export.sml
</pre><p>
<tt>export.h</tt> now contains the following C prototypes. 
</p>

<pre>Int8 f (Int32 x0, Real64 x1, Int8 x2);
Pointer f2 (Word8 x0);
void f3 ();
void f4 (Int32 x0);
extern Int32 zzz;
</pre><p>
Use <tt>export.h</tt> in a C program, <tt>ffi-export.c</tt>, as follows. 
</p>
<p>
<pre class=code>#<B><FONT COLOR="#5F9EA0">include</FONT></B> <B><FONT COLOR="#BC8F8F">&lt;stdio.h&gt;</FONT></B>
#<B><FONT COLOR="#5F9EA0">include</FONT></B> <B><FONT COLOR="#BC8F8F">&quot;export.h&quot;</FONT></B>

<B><FONT COLOR="#228B22">void</FONT></B> <B><FONT COLOR="#0000FF">g</FONT></B> () {
        Char8 c;

        fprintf (stderr, <B><FONT COLOR="#BC8F8F">&quot;g starting\n&quot;</FONT></B>);
        c = f (13, 17.15, <B><FONT COLOR="#BC8F8F">'a'</FONT></B>);
        fprintf (stderr, <B><FONT COLOR="#BC8F8F">&quot;g done  char = %c\n&quot;</FONT></B>, c);
}

Pointer <B><FONT COLOR="#0000FF">g2</FONT></B> () {
        Pointer res;
        fprintf (stderr, <B><FONT COLOR="#BC8F8F">&quot;g2 starting\n&quot;</FONT></B>);
        res = f2 (0xFF);
        fprintf (stderr, <B><FONT COLOR="#BC8F8F">&quot;g2 done\n&quot;</FONT></B>);
        <B><FONT COLOR="#A020F0">return</FONT></B> res;
}

<B><FONT COLOR="#228B22">void</FONT></B> <B><FONT COLOR="#0000FF">g3</FONT></B> () {
        fprintf (stderr, <B><FONT COLOR="#BC8F8F">&quot;g3 starting\n&quot;</FONT></B>);
        f3 ();
        fprintf (stderr, <B><FONT COLOR="#BC8F8F">&quot;g3 done\n&quot;</FONT></B>);
}

<B><FONT COLOR="#228B22">void</FONT></B> <B><FONT COLOR="#0000FF">g4</FONT></B> (Int32 i) {
        fprintf (stderr, <B><FONT COLOR="#BC8F8F">&quot;g4 (%d)\n&quot;</FONT></B>, i);
        f4 (i);
}

<B><FONT COLOR="#228B22">void</FONT></B> <B><FONT COLOR="#0000FF">g5</FONT></B> () {
        fprintf (stderr, <B><FONT COLOR="#BC8F8F">&quot;g5 ()\n&quot;</FONT></B>);
        fprintf (stderr, <B><FONT COLOR="#BC8F8F">&quot;zzz = %i\n&quot;</FONT></B>, zzz);
        fprintf (stderr, <B><FONT COLOR="#BC8F8F">&quot;g5 done\n&quot;</FONT></B>);
}
</PRE>
 
</p>
<p>
Compile <tt>ffi-export.c</tt> and <tt>export.sml</tt>. 
<pre>% gcc -c ffi-export.c
% mlton -default-ann 'allowFFI true' \
         export.sml ffi-export.o
</pre>
</p>
<p>
Finally, run <tt>export</tt>. 
<pre>% ./export
g starting
...
g4 (0)
success
</pre>
</p>
<h2 id="head-a479c9c34e878d07b4d67a73a48f432ad7dc53c8">Download</h2>

    <ul>

    <li>
<p>
 <a href = "http://mlton.org/cgi-bin/viewsvn.cgi/*checkout*/mlton/tags/on-MLTONWIKIVERSION-release/doc/examples/ffi/export.sml"><img src="moin-www.png" alt="[WWW]" height="11" width="11">export.sml</a> 
</p>
</li>
    <li>
<p>
 <a href = "http://mlton.org/cgi-bin/viewsvn.cgi/*checkout*/mlton/tags/on-MLTONWIKIVERSION-release/doc/examples/ffi/ffi-export.c"><img src="moin-www.png" alt="[WWW]" height="11" width="11">ffi-export.c</a> 
</p>
</li>
</ul>

</div>



<p>
<hr>
Last edited on 2006-11-02 17:34:21 by <span title="76.16.241.4"><a href="MatthewFluet">MatthewFluet</a></span>.
</body></html>
