Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / localhost / CallingFromSMLToCFunctionPointer
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 <meta name="generator" content="AsciiDoc 8.6.9">
6 <title>CallingFromSMLToCFunctionPointer</title>
7 <link rel="stylesheet" href="./asciidoc.css" type="text/css">
8 <link rel="stylesheet" href="./pygments.css" type="text/css">
9
10
11 <script type="text/javascript" src="./asciidoc.js"></script>
12 <script type="text/javascript">
13 /*<![CDATA[*/
14 asciidoc.install();
15 /*]]>*/
16 </script>
17 <link rel="stylesheet" href="./mlton.css" type="text/css">
18 </head>
19 <body class="article">
20 <div id="banner">
21 <div id="banner-home">
22 <a href="./Home">MLton 20180207</a>
23 </div>
24 </div>
25 <div id="header">
26 <h1>CallingFromSMLToCFunctionPointer</h1>
27 </div>
28 <div id="content">
29 <div id="preamble">
30 <div class="sectionbody">
31 <div class="paragraph"><p>Just as MLton can <a href="CallingFromSMLToC">directly call C functions</a>, it
32 is possible to make indirect function calls; that is, function calls
33 through a function pointer. MLton extends the syntax of SML to allow
34 expressions like the following:</p></div>
35 <div class="listingblock">
36 <div class="content monospaced">
37 <pre>_import * : MLton.Pointer.t -&gt; real * char -&gt; int;</pre>
38 </div></div>
39 <div class="paragraph"><p>This expression denotes a function of type</p></div>
40 <div class="listingblock">
41 <div class="content"><div class="highlight"><pre><span class="n">MLton</span><span class="p">.</span><span class="n">Pointer</span><span class="p">.</span><span class="n">t</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">real</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">char</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">int</span><span class="w"></span>
42 </pre></div></div></div>
43 <div class="paragraph"><p>whose behavior is implemented by calling the C function at the address
44 denoted by the <span class="monospaced">MLton.Pointer.t</span> argument, and supplying the C
45 function two arguments, a <span class="monospaced">double</span> and an <span class="monospaced">int</span>. The C function
46 pointer may be obtained, for example, by the dynamic linking loader
47 (<span class="monospaced">dlopen</span>, <span class="monospaced">dlsym</span>, &#8230;).</p></div>
48 <div class="paragraph"><p>The general form of an indirect <span class="monospaced">_import</span> expression is:</p></div>
49 <div class="listingblock">
50 <div class="content monospaced">
51 <pre>_import * attr... : cPtrTy -&gt; cFuncTy;</pre>
52 </div></div>
53 <div class="paragraph"><p>The type and the semicolon are not optional.</p></div>
54 </div>
55 </div>
56 <div class="sect1">
57 <h2 id="_example">Example</h2>
58 <div class="sectionbody">
59 <div class="paragraph"><p>This example uses <span class="monospaced">dlopen</span> and friends (imported using normal
60 <span class="monospaced">_import</span>) to dynamically load the math library (<span class="monospaced">libm</span>) and call the
61 <span class="monospaced">cos</span> function. Suppose <span class="monospaced">iimport.sml</span> contains the following.</p></div>
62 <div class="listingblock">
63 <div class="content"><div class="highlight"><pre><span class="k">signature</span><span class="w"> </span><span class="n">DYN_LINK</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
64 <span class="w"> </span><span class="k">sig</span><span class="w"></span>
65 <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">hndl</span><span class="w"></span>
66 <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">mode</span><span class="w"></span>
67 <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">fptr</span><span class="w"></span>
68
69 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlopen</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">mode</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">hndl</span><span class="w"></span>
70 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlsym</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">hndl</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">fptr</span><span class="w"></span>
71 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlclose</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">hndl</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="w"></span>
72
73 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">RTLD_LAZY</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">mode</span><span class="w"></span>
74 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">RTLD_NOW</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">mode</span><span class="w"></span>
75 <span class="w"> </span><span class="k">end</span><span class="w"></span>
76
77 <span class="k">structure</span><span class="w"> </span><span class="n">DynLink</span><span class="w"> </span><span class="p">:&gt;</span><span class="w"> </span><span class="n">DYN_LINK</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
78 <span class="w"> </span><span class="k">struct</span><span class="w"></span>
79 <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">hndl</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">MLton</span><span class="p">.</span><span class="n">Pointer</span><span class="p">.</span><span class="n">t</span><span class="w"></span>
80 <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">mode</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">Word32</span><span class="p">.</span><span class="n">word</span><span class="w"></span>
81 <span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">fptr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">MLton</span><span class="p">.</span><span class="n">Pointer</span><span class="p">.</span><span class="n">t</span><span class="w"></span>
82
83 <span class="w"> </span><span class="cm">(* These symbols come from a system libray, so the default import scope</span>
84 <span class="cm"> * of external is correct.</span>
85 <span class="cm"> *)</span><span class="w"></span>
86 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlopen</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
87 <span class="w"> </span><span class="p">_</span><span class="n">import</span><span class="w"> </span><span class="s">&quot;dlopen&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">mode</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">hndl</span><span class="p">;</span><span class="w"></span>
88 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlerror</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
89 <span class="w"> </span><span class="p">_</span><span class="n">import</span><span class="w"> </span><span class="s">&quot;dlerror&quot;</span><span class="p">:</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">MLton</span><span class="p">.</span><span class="n">Pointer</span><span class="p">.</span><span class="n">t</span><span class="p">;</span><span class="w"></span>
90 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlsym</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
91 <span class="w"> </span><span class="p">_</span><span class="n">import</span><span class="w"> </span><span class="s">&quot;dlsym&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">hndl</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">fptr</span><span class="p">;</span><span class="w"></span>
92 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlclose</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
93 <span class="w"> </span><span class="p">_</span><span class="n">import</span><span class="w"> </span><span class="s">&quot;dlclose&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">hndl</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">Int32</span><span class="p">.</span><span class="n">int</span><span class="p">;</span><span class="w"></span>
94
95 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">RTLD_LAZY</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mh">0wx00001</span><span class="w"> </span><span class="cm">(* Lazy function call binding. *)</span><span class="w"></span>
96 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">RTLD_NOW</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mh">0wx00002</span><span class="w"> </span><span class="cm">(* Immediate function call binding. *)</span><span class="w"></span>
97
98 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlerror</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"></span>
99 <span class="w"> </span><span class="k">let</span><span class="w"></span>
100 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">addr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">dlerror</span><span class="w"> </span><span class="p">()</span><span class="w"></span>
101 <span class="w"> </span><span class="k">in</span><span class="w"></span>
102 <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">addr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">MLton</span><span class="p">.</span><span class="n">Pointer</span><span class="p">.</span><span class="n">null</span><span class="w"></span>
103 <span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="n">NONE</span><span class="w"></span>
104 <span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">let</span><span class="w"></span>
105 <span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">loop</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="p">,</span><span class="w"> </span><span class="n">cs</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
106 <span class="w"> </span><span class="k">let</span><span class="w"></span>
107 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">MLton</span><span class="p">.</span><span class="n">Pointer</span><span class="p">.</span><span class="n">getWord8</span><span class="w"> </span><span class="p">(</span><span class="n">addr</span><span class="p">,</span><span class="w"> </span><span class="n">index</span><span class="p">)</span><span class="w"></span>
108 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">Byte</span><span class="p">.</span><span class="n">byteToChar</span><span class="w"> </span><span class="n">w</span><span class="w"></span>
109 <span class="w"> </span><span class="k">in</span><span class="w"></span>
110 <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">#</span><span class="s">&quot;</span><span class="se">\000</span><span class="s">&quot;</span><span class="w"></span>
111 <span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="n">SOME</span><span class="w"> </span><span class="p">(</span><span class="n">implode</span><span class="w"> </span><span class="p">(</span><span class="n">rev</span><span class="w"> </span><span class="n">cs</span><span class="p">))</span><span class="w"></span>
112 <span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="n">loop</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="n">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">c::cs</span><span class="p">)</span><span class="w"></span>
113 <span class="w"> </span><span class="k">end</span><span class="w"></span>
114 <span class="w"> </span><span class="k">in</span><span class="w"></span>
115 <span class="w"> </span><span class="n">loop</span><span class="w"> </span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="p">[])</span><span class="w"></span>
116 <span class="w"> </span><span class="k">end</span><span class="w"></span>
117 <span class="w"> </span><span class="k">end</span><span class="w"></span>
118
119 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlopen</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="p">(</span><span class="n">filename</span><span class="p">,</span><span class="w"> </span><span class="n">mode</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"></span>
120 <span class="w"> </span><span class="k">let</span><span class="w"></span>
121 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">filename</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">filename</span><span class="w"> </span><span class="n">^</span><span class="w"> </span><span class="s">&quot;</span><span class="se">\000</span><span class="s">&quot;</span><span class="w"></span>
122 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">hndl</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">dlopen</span><span class="w"> </span><span class="p">(</span><span class="n">filename</span><span class="p">,</span><span class="w"> </span><span class="n">mode</span><span class="p">)</span><span class="w"></span>
123 <span class="w"> </span><span class="k">in</span><span class="w"></span>
124 <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">hndl</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">MLton</span><span class="p">.</span><span class="n">Pointer</span><span class="p">.</span><span class="n">null</span><span class="w"></span>
125 <span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="n">Fail</span><span class="w"> </span><span class="p">(</span><span class="k">case</span><span class="w"> </span><span class="n">dlerror</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="k">of</span><span class="w"></span>
126 <span class="w"> </span><span class="n">NONE</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="s">&quot;???&quot;</span><span class="w"></span>
127 <span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">SOME</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">s</span><span class="p">)</span><span class="w"></span>
128 <span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="n">hndl</span><span class="w"></span>
129 <span class="w"> </span><span class="k">end</span><span class="w"></span>
130
131 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlsym</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="p">(</span><span class="n">hndl</span><span class="p">,</span><span class="w"> </span><span class="n">symbol</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"></span>
132 <span class="w"> </span><span class="k">let</span><span class="w"></span>
133 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">symbol</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">symbol</span><span class="w"> </span><span class="n">^</span><span class="w"> </span><span class="s">&quot;</span><span class="se">\000</span><span class="s">&quot;</span><span class="w"></span>
134 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">fptr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">dlsym</span><span class="w"> </span><span class="p">(</span><span class="n">hndl</span><span class="p">,</span><span class="w"> </span><span class="n">symbol</span><span class="p">)</span><span class="w"></span>
135 <span class="w"> </span><span class="k">in</span><span class="w"></span>
136 <span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">dlerror</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="k">of</span><span class="w"></span>
137 <span class="w"> </span><span class="n">NONE</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">fptr</span><span class="w"></span>
138 <span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">SOME</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="n">Fail</span><span class="w"> </span><span class="n">s</span><span class="w"></span>
139 <span class="w"> </span><span class="k">end</span><span class="w"></span>
140
141 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dlclose</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">hndl</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"></span>
142 <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">MLton</span><span class="p">.</span><span class="n">Platform</span><span class="p">.</span><span class="n">OS</span><span class="p">.</span><span class="n">host</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">MLton</span><span class="p">.</span><span class="n">Platform</span><span class="p">.</span><span class="n">OS</span><span class="p">.</span><span class="n">Darwin</span><span class="w"></span>
143 <span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="cm">(* Darwin reports the following error message if you</span>
144 <span class="cm"> * try to close a dynamic library.</span>
145 <span class="cm"> * &quot;dynamic libraries cannot be closed&quot;</span>
146 <span class="cm"> * So, we disable dlclose on Darwin.</span>
147 <span class="cm"> *)</span><span class="w"></span>
148 <span class="w"> </span><span class="k">else</span><span class="w"></span>
149 <span class="w"> </span><span class="k">let</span><span class="w"></span>
150 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">dlclose</span><span class="w"> </span><span class="n">hndl</span><span class="w"></span>
151 <span class="w"> </span><span class="k">in</span><span class="w"></span>
152 <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">0</span><span class="w"></span>
153 <span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="p">()</span><span class="w"></span>
154 <span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">raise</span><span class="w"> </span><span class="n">Fail</span><span class="w"> </span><span class="p">(</span><span class="k">case</span><span class="w"> </span><span class="n">dlerror</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="k">of</span><span class="w"></span>
155 <span class="w"> </span><span class="n">NONE</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="s">&quot;???&quot;</span><span class="w"></span>
156 <span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">SOME</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">s</span><span class="p">)</span><span class="w"></span>
157 <span class="w"> </span><span class="k">end</span><span class="w"></span>
158 <span class="w"> </span><span class="k">end</span><span class="w"></span>
159
160 <span class="k">val</span><span class="w"> </span><span class="n">dll</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
161 <span class="w"> </span><span class="k">let</span><span class="w"></span>
162 <span class="w"> </span><span class="k">open</span><span class="w"> </span><span class="n">MLton</span><span class="p">.</span><span class="n">Platform</span><span class="p">.</span><span class="n">OS</span><span class="w"></span>
163 <span class="w"> </span><span class="k">in</span><span class="w"></span>
164 <span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="n">host</span><span class="w"> </span><span class="k">of</span><span class="w"></span>
165 <span class="w"> </span><span class="n">Cygwin</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="s">&quot;cygwin1.dll&quot;</span><span class="w"></span>
166 <span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">Darwin</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="s">&quot;libm.dylib&quot;</span><span class="w"></span>
167 <span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="p">_</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="s">&quot;libm.so&quot;</span><span class="w"></span>
168 <span class="w"> </span><span class="k">end</span><span class="w"></span>
169
170 <span class="k">val</span><span class="w"> </span><span class="n">hndl</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">DynLink</span><span class="p">.</span><span class="n">dlopen</span><span class="w"> </span><span class="p">(</span><span class="n">dll</span><span class="p">,</span><span class="w"> </span><span class="n">DynLink</span><span class="p">.</span><span class="n">RTLD_LAZY</span><span class="p">)</span><span class="w"></span>
171
172 <span class="k">local</span><span class="w"></span>
173 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">double_to_double</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
174 <span class="w"> </span><span class="p">_</span><span class="n">import</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">DynLink</span><span class="p">.</span><span class="n">fptr</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">real</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">real</span><span class="p">;</span><span class="w"></span>
175 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">cos_fptr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">DynLink</span><span class="p">.</span><span class="n">dlsym</span><span class="w"> </span><span class="p">(</span><span class="n">hndl</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;cos&quot;</span><span class="p">)</span><span class="w"></span>
176 <span class="k">in</span><span class="w"></span>
177 <span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">cos</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">double_to_double</span><span class="w"> </span><span class="n">cos_fptr</span><span class="w"></span>
178 <span class="k">end</span><span class="w"></span>
179
180 <span class="k">val</span><span class="w"> </span><span class="p">_</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">print</span><span class="w"> </span><span class="p">(</span><span class="n">concat</span><span class="w"> </span><span class="p">[</span><span class="s">&quot; Math.cos(2.0) = &quot;</span><span class="p">,</span><span class="w"> </span><span class="n">Real</span><span class="p">.</span><span class="n">toString</span><span class="w"> </span><span class="p">(</span><span class="n">Math</span><span class="p">.</span><span class="n">cos</span><span class="w"> </span><span class="mf">2.0</span><span class="p">),</span><span class="w"> </span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"></span>
181 <span class="w"> </span><span class="s">&quot;libm.so::cos(2.0) = &quot;</span><span class="p">,</span><span class="w"> </span><span class="n">Real</span><span class="p">.</span><span class="n">toString</span><span class="w"> </span><span class="p">(</span><span class="n">cos</span><span class="w"> </span><span class="mf">2.0</span><span class="p">),</span><span class="w"> </span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">])</span><span class="w"></span>
182
183 <span class="k">val</span><span class="w"> </span><span class="p">_</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">DynLink</span><span class="p">.</span><span class="n">dlclose</span><span class="w"> </span><span class="n">hndl</span><span class="w"></span>
184 </pre></div></div></div>
185 <div class="paragraph"><p>Compile and run <span class="monospaced">iimport.sml</span>.</p></div>
186 <div class="listingblock">
187 <div class="content monospaced">
188 <pre>% mlton -default-ann 'allowFFI true' \
189 -target-link-opt linux -ldl \
190 -target-link-opt solaris -ldl \
191 iimport.sml
192 % iimport
193 Math.cos(2.0) = ~0.416146836547
194 libm.so::cos(2.0) = ~0.416146836547</pre>
195 </div></div>
196 <div class="paragraph"><p>This example also shows the <span class="monospaced">-target-link-opt</span> option, which uses the
197 switch when linking only when on the specified platform. Compile with
198 <span class="monospaced">-verbose 1</span> to see in more detail what&#8217;s being passed to <span class="monospaced">gcc</span>.</p></div>
199 </div>
200 </div>
201 <div class="sect1">
202 <h2 id="_download">Download</h2>
203 <div class="sectionbody">
204 <div class="ulist"><ul>
205 <li>
206 <p>
207 <a href="https://raw.github.com/MLton/mlton/master/doc/examples/ffi/iimport.sml"><span class="monospaced">iimport.sml</span></a>
208 </p>
209 </li>
210 </ul></div>
211 </div>
212 </div>
213 </div>
214 <div id="footnotes"><hr></div>
215 <div id="footer">
216 <div id="footer-text">
217 </div>
218 <div id="footer-badges">
219 </div>
220 </div>
221 </body>
222 </html>