Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / doc / guide / localhost / CallingFromSMLToCFunctionPointer
CommitLineData
7f918cf1
CE
1<!DOCTYPE html>\r
2<html lang="en">\r
3<head>\r
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\r
5<meta name="generator" content="AsciiDoc 8.6.9">\r
6<title>CallingFromSMLToCFunctionPointer</title>\r
7<link rel="stylesheet" href="./asciidoc.css" type="text/css">\r
8<link rel="stylesheet" href="./pygments.css" type="text/css">\r
9\r
10\r
11<script type="text/javascript" src="./asciidoc.js"></script>\r
12<script type="text/javascript">\r
13/*<![CDATA[*/\r
14asciidoc.install();\r
15/*]]>*/\r
16</script>\r
17<link rel="stylesheet" href="./mlton.css" type="text/css">\r
18</head>\r
19<body class="article">\r
20<div id="banner">\r
21<div id="banner-home">\r
22<a href="./Home">MLton 20180207</a>\r
23</div>\r
24</div>\r
25<div id="header">\r
26<h1>CallingFromSMLToCFunctionPointer</h1>\r
27</div>\r
28<div id="content">\r
29<div id="preamble">\r
30<div class="sectionbody">\r
31<div class="paragraph"><p>Just as MLton can <a href="CallingFromSMLToC">directly call C functions</a>, it\r
32is possible to make indirect function calls; that is, function calls\r
33through a function pointer. MLton extends the syntax of SML to allow\r
34expressions like the following:</p></div>\r
35<div class="listingblock">\r
36<div class="content monospaced">\r
37<pre>_import * : MLton.Pointer.t -&gt; real * char -&gt; int;</pre>\r
38</div></div>\r
39<div class="paragraph"><p>This expression denotes a function of type</p></div>\r
40<div class="listingblock">\r
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>\r
42</pre></div></div></div>\r
43<div class="paragraph"><p>whose behavior is implemented by calling the C function at the address\r
44denoted by the <span class="monospaced">MLton.Pointer.t</span> argument, and supplying the C\r
45function two arguments, a <span class="monospaced">double</span> and an <span class="monospaced">int</span>. The C function\r
46pointer may be obtained, for example, by the dynamic linking loader\r
47(<span class="monospaced">dlopen</span>, <span class="monospaced">dlsym</span>, &#8230;).</p></div>\r
48<div class="paragraph"><p>The general form of an indirect <span class="monospaced">_import</span> expression is:</p></div>\r
49<div class="listingblock">\r
50<div class="content monospaced">\r
51<pre>_import * attr... : cPtrTy -&gt; cFuncTy;</pre>\r
52</div></div>\r
53<div class="paragraph"><p>The type and the semicolon are not optional.</p></div>\r
54</div>\r
55</div>\r
56<div class="sect1">\r
57<h2 id="_example">Example</h2>\r
58<div class="sectionbody">\r
59<div class="paragraph"><p>This example uses <span class="monospaced">dlopen</span> and friends (imported using normal\r
60<span class="monospaced">_import</span>) to dynamically load the math library (<span class="monospaced">libm</span>) and call the\r
61<span class="monospaced">cos</span> function. Suppose <span class="monospaced">iimport.sml</span> contains the following.</p></div>\r
62<div class="listingblock">\r
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>\r
64<span class="w"> </span><span class="k">sig</span><span class="w"></span>\r
65<span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">hndl</span><span class="w"></span>\r
66<span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">mode</span><span class="w"></span>\r
67<span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">fptr</span><span class="w"></span>\r
68\r
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>\r
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>\r
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>\r
72\r
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>\r
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>\r
75<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
76\r
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>\r
78<span class="w"> </span><span class="k">struct</span><span class="w"></span>\r
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>\r
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>\r
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>\r
82\r
83<span class="w"> </span><span class="cm">(* These symbols come from a system libray, so the default import scope</span>\r
84<span class="cm"> * of external is correct.</span>\r
85<span class="cm"> *)</span><span class="w"></span>\r
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>\r
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>\r
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>\r
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>\r
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>\r
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>\r
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>\r
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>\r
94\r
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>\r
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>\r
97\r
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>\r
99<span class="w"> </span><span class="k">let</span><span class="w"></span>\r
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>\r
101<span class="w"> </span><span class="k">in</span><span class="w"></span>\r
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>\r
103<span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="n">NONE</span><span class="w"></span>\r
104<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">let</span><span class="w"></span>\r
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>\r
106<span class="w"> </span><span class="k">let</span><span class="w"></span>\r
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>\r
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>\r
109<span class="w"> </span><span class="k">in</span><span class="w"></span>\r
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>\r
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>\r
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>\r
113<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
114<span class="w"> </span><span class="k">in</span><span class="w"></span>\r
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>\r
116<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
117<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
118\r
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>\r
120<span class="w"> </span><span class="k">let</span><span class="w"></span>\r
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>\r
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>\r
123<span class="w"> </span><span class="k">in</span><span class="w"></span>\r
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>\r
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>\r
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>\r
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>\r
128<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="n">hndl</span><span class="w"></span>\r
129<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
130\r
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>\r
132<span class="w"> </span><span class="k">let</span><span class="w"></span>\r
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>\r
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>\r
135<span class="w"> </span><span class="k">in</span><span class="w"></span>\r
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>\r
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>\r
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>\r
139<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
140\r
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>\r
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>\r
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>\r
144<span class="cm"> * try to close a dynamic library.</span>\r
145<span class="cm"> * &quot;dynamic libraries cannot be closed&quot;</span>\r
146<span class="cm"> * So, we disable dlclose on Darwin.</span>\r
147<span class="cm"> *)</span><span class="w"></span>\r
148<span class="w"> </span><span class="k">else</span><span class="w"></span>\r
149<span class="w"> </span><span class="k">let</span><span class="w"></span>\r
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>\r
151<span class="w"> </span><span class="k">in</span><span class="w"></span>\r
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>\r
153<span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="p">()</span><span class="w"></span>\r
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>\r
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>\r
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>\r
157<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
158<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
159\r
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>\r
161<span class="w"> </span><span class="k">let</span><span class="w"></span>\r
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>\r
163<span class="w"> </span><span class="k">in</span><span class="w"></span>\r
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>\r
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>\r
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>\r
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>\r
168<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
169\r
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>\r
171\r
172<span class="k">local</span><span class="w"></span>\r
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>\r
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>\r
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>\r
176<span class="k">in</span><span class="w"></span>\r
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>\r
178<span class="k">end</span><span class="w"></span>\r
179\r
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>\r
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>\r
182\r
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>\r
184</pre></div></div></div>\r
185<div class="paragraph"><p>Compile and run <span class="monospaced">iimport.sml</span>.</p></div>\r
186<div class="listingblock">\r
187<div class="content monospaced">\r
188<pre>% mlton -default-ann 'allowFFI true' \\r
189 -target-link-opt linux -ldl \\r
190 -target-link-opt solaris -ldl \\r
191 iimport.sml\r
192% iimport\r
193 Math.cos(2.0) = ~0.416146836547\r
194libm.so::cos(2.0) = ~0.416146836547</pre>\r
195</div></div>\r
196<div class="paragraph"><p>This example also shows the <span class="monospaced">-target-link-opt</span> option, which uses the\r
197switch when linking only when on the specified platform. Compile with\r
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>\r
199</div>\r
200</div>\r
201<div class="sect1">\r
202<h2 id="_download">Download</h2>\r
203<div class="sectionbody">\r
204<div class="ulist"><ul>\r
205<li>\r
206<p>\r
207<a href="https://raw.github.com/MLton/mlton/master/doc/examples/ffi/iimport.sml"><span class="monospaced">iimport.sml</span></a>\r
208</p>\r
209</li>\r
210</ul></div>\r
211</div>\r
212</div>\r
213</div>\r
214<div id="footnotes"><hr></div>\r
215<div id="footer">\r
216<div id="footer-text">\r
217</div>\r
218<div id="footer-badges">\r
219</div>\r
220</div>\r
221</body>\r
222</html>\r