blob: 2809a28677e5532d5008aae130470c12f333017a [file] [log] [blame]
<!DOCTYPE html>
<html class="no-js">
<head lang="en-us">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=10" />
<title>Foreign Function Interface - Eclipse Mita</title>
<meta name="generator" content="Hugo 0.42.1" />
<meta name="description" content="The documentation of Eclipse Mita.">
<link rel="canonical" href="../../language/foreignfunctioninterface/">
<meta property="og:url" content="/language/foreignfunctioninterface/">
<meta property="og:title" content="Eclipse Mita">
<meta property="og:image" content="/images/mita.svg">
<meta name="apple-mobile-web-app-title" content="Eclipse Mita">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="shortcut icon" type="image/x-icon" href="../../images/favicon.ico">
<link rel="icon" type="image/x-icon" href="../../images/favicon.ico">
<style>
@font-face {
font-family: 'Icon';
src: url('/fonts/icon.eot');
src: url('/fonts/icon.eot')
format('embedded-opentype'),
url('/fonts/icon.woff')
format('woff'),
url('/fonts/icon.ttf')
format('truetype'),
url('/fonts/icon.svg')
format('svg');
font-weight: normal;
font-style: normal;
}
</style>
<link rel="stylesheet" href="../../stylesheets/application.css">
<link rel="stylesheet" href="../../stylesheets/temporary.css">
<link rel="stylesheet" href="../../stylesheets/palettes.css">
<link rel="stylesheet" href="../../stylesheets/highlight/highlight.css">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Ubuntu:400,700|Ubuntu&#43;Mono">
<style>
body, input {
font-family: 'Ubuntu', Helvetica, Arial, sans-serif;
}
pre, code {
font-family: 'Ubuntu Mono', 'Courier New', 'Courier', monospace;
}
</style>
<link rel="stylesheet" href="../../css/custom.css">
<script src="../../javascripts/modernizr.js"></script>
</head>
<body class="palette-primary-blue-grey palette-accent-light-blue">
<div class="backdrop">
<div class="backdrop-paper"></div>
</div>
<input class="toggle" type="checkbox" id="toggle-drawer">
<input class="toggle" type="checkbox" id="toggle-search">
<label class="toggle-button overlay" for="toggle-drawer"></label>
<header class="header">
<nav aria-label="Header">
<div class="bar default">
<div class="button button-menu" role="button" aria-label="Menu">
<label class="toggle-button icon icon-menu" for="toggle-drawer">
<span></span>
</label>
</div>
<div class="stretch">
<div class="title">
Foreign Function Interface
</div>
</div>
<div class="button button-twitter" role="button" aria-label="Twitter">
<a href="https://twitter.com/eclipse_mita" title="@eclipse_mita on Twitter" target="_blank" class="toggle-button icon icon-twitter"></a>
</div>
<div class="button button-github" role="button" aria-label="GitHub">
<a href="https://github.com/eclipse/mita" title="@eclipse/mita on GitHub" target="_blank" class="toggle-button icon icon-github"></a>
</div>
</div>
<div class="bar search">
<div class="button button-close" role="button" aria-label="Close">
<label class="toggle-button icon icon-back" for="toggle-search"></label>
</div>
<div class="stretch">
<div class="field">
<input class="query" type="text" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck>
</div>
</div>
<div class="button button-reset" role="button" aria-label="Search">
<button class="toggle-button icon icon-close" id="reset-search"></button>
</div>
</div>
</nav>
</header>
<main class="main">
<div class="drawer">
<nav aria-label="Navigation">
<a href="../../" class="project">
<div class="banner">
<div class="logo">
<img src="../../images/mita.svg">
</div>
<div class="name">
<strong>Eclipse Mita </strong>
</div>
</div>
</a>
<div class="scrollable">
<div class="wrapper">
<div class="toc">
<ul>
<li>
<a title="Download" href="http://github.com/eclipse/mita">
Download
</a>
</li>
<li>
<a title="Concepts" href="../../concepts/">
Concepts
</a>
</li>
<li>
<span class="section">Language</span>
<ul>
<a title="Introduction" href="../../language/introduction/">
Introduction
</a>
<a title="Basics" href="../../language/basics/">
Basics
</a>
<a title="Packages" href="../../language/packages/">
Packages
</a>
<a title="System Setup" href="../../language/setup/">
System Setup
</a>
<a title="Types" href="../../language/types/">
Types
</a>
<a title="Arrays" href="../../language/arrays/">
Arrays
</a>
<a title="Functions" href="../../language/functions/">
Functions
</a>
<a class="current" title="Foreign Function Interface" href="../../language/foreignfunctioninterface/">
Foreign Function Interface
</a>
<ul id="scrollspy">
</ul>
<a title="Events" href="../../language/events/">
Events
</a>
<a title="Exceptions" href="../../language/exceptions/">
Exceptions
</a>
</ul>
</li>
<li>
<span class="section">Platforms</span>
<ul>
<a title="XDK110" href="../../platforms/xdk110/">
XDK110
</a>
</ul>
</li>
</ul>
</div>
</div>
</div>
</nav>
</div>
<article class="article">
<div class="wrapper">
<h1>Foreign Function Interface </h1>
<p>Mita transpiles to C code, i.e. the compiler produces C code rather than a binary executable.
This begs the question if we can call existing C code from within Mita programs.
Such integration of the &ldquo;target language&rdquo; is referred to as <em>foreign function interface</em> (or <em>FFI</em> in short) because the functions we wish to call from within Mita are defined in a foreign language: C.
Other languages sport similar concepts, for example <em>TypeScript</em> supports <a href="https://basarat.gitbooks.io/typescript/docs/types/ambient/d.ts.html">declarations</a> which allow you to use code written in JavaScript (the language TypeScript compiles to).</p>
<p>Calling native C functions is useful if we want to re-use existing libraries, or for the things which are easier to express in C than they are to express in Mita.
Suppose you wanted to connect a new sensor to your device and the sensor came with a driver library written in C.
Using the foreign function interface you can integrate and use that driver library from within Mita.</p>
<h2 id="native-functions">Native Functions</h2>
<p>To make a function written in native C known to Mita you have to declare them in an Mita file, e.g.:</p>
<div class="highlight"><pre class="chroma"><code class="language-TypeScript" data-lang="TypeScript"><span class="kr">native</span> <span class="nx">unchecked</span> <span class="nx">fn</span> <span class="nx">abs</span><span class="p">(</span><span class="nx">n</span> : <span class="kt">int32</span><span class="p">)</span> <span class="o">:</span> <span class="nx">int32</span>
<span class="nx">header</span> <span class="s2">&#34;math.h&#34;</span><span class="p">;</span></code></pre></div>
<p>The header which we have named during the declaration of the native function will be automatically included in the generated C code where necessary.
With the <code>abs</code> function declared like that we can use it just like a regular Mita function.</p>
<div class="highlight"><pre class="chroma"><code class="language-TypeScript" data-lang="TypeScript"><span class="kr">package</span> <span class="nx">main</span><span class="p">;</span>
<span class="kr">import</span> <span class="nx">platforms</span><span class="p">.</span><span class="nx">xdk110</span><span class="p">;</span>
<span class="nx">every</span> <span class="mi">1</span> <span class="nx">second</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">xAxisAcceleration</span> <span class="o">=</span> <span class="nx">acc</span>
<span class="nx">println</span><span class="p">(</span><span class="sb">`Absolute X axis acceleration: </span><span class="si">${</span><span class="nx">abs</span><span class="p">(</span><span class="nx">accelerometer</span><span class="p">.</span><span class="nx">x_axis</span><span class="p">.</span><span class="nx">read</span><span class="p">())</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
<span class="p">}</span></code></pre></div>
<h2 id="unchecked-vs-checked">Unchecked vs Checked</h2>
<p>Notice the <code>unchecked</code> keyword in the example above.
Mita supports exceptions which map to special return values in the generated C code.
The <code>unchecked</code> keyword and its counterpart <code>checked</code> tell the compiler if it should use the Mita calling convention which handles exceptions, or the C calling convention where the return value is not used for exceptions.</p>
<p>Let&rsquo;s look at both calling conventions in detail. For both calling conventions we will see the Mita declaration and the corresponding C header that the compiler expects.</p>
<h3 id="unchecked">Unchecked</h3>
<div class="highlight"><pre class="chroma"><code class="language-TypeScript" data-lang="TypeScript"><span class="kr">native</span> <span class="nx">unchecked</span> <span class="nx">fn</span> <span class="nx">foobar</span><span class="p">(</span><span class="nx">n</span> : <span class="kt">int32</span><span class="p">)</span> <span class="o">:</span> <span class="nx">int32</span>
<span class="nx">header</span> <span class="s2">&#34;unfoobar.h&#34;</span><span class="p">;</span>
<span class="kr">native</span> <span class="nx">unchecked</span> <span class="nx">fn</span> <span class="nx">foobarWithRef</span><span class="p">(</span><span class="nx">ref</span> <span class="o">:</span> <span class="o">&amp;</span><span class="nx">int32</span><span class="p">)</span> <span class="o">:</span> <span class="nx">int32</span>
<span class="nx">header</span> <span class="s2">&#34;unfoobar.h&#34;</span><span class="p">;</span>
<span class="kr">native</span> <span class="nx">unchecked</span> <span class="nx">fn</span> <span class="nx">foobarVoid</span><span class="p">(</span><span class="nx">n</span> : <span class="kt">int32</span><span class="p">)</span> <span class="o">:</span> <span class="k">void</span>
<span class="nx">header</span> <span class="s2">&#34;unfoobar.h&#34;</span><span class="p">;</span></code></pre></div>
<p>expects <code>unfoobar.h</code> to look something like</p>
<div class="highlight"><pre class="chroma"><code class="language-C" data-lang="C"><span class="cp">#include</span> <span class="cpf">&lt;stdint.h&gt;</span><span class="cp">
</span><span class="cp"></span>
<span class="n">int32_t</span> <span class="nf">foobar</span><span class="p">(</span><span class="n">int32_t</span> <span class="n">n</span><span class="p">);</span>
<span class="n">int32_t</span> <span class="nf">foobarWithRef</span><span class="p">(</span><span class="n">int32_t</span><span class="o">*</span> <span class="n">ref</span><span class="p">);</span>
<span class="kt">void</span> <span class="nf">foobarVoid</span><span class="p">(</span><span class="n">int32_t</span> <span class="n">n</span><span class="p">);</span></code></pre></div>
<h3 id="checked">Checked</h3>
<div class="highlight"><pre class="chroma"><code class="language-TypeScript" data-lang="TypeScript"><span class="kr">native</span> <span class="nx">checked</span> <span class="nx">fn</span> <span class="nx">foobar</span><span class="p">(</span><span class="nx">n</span> : <span class="kt">int32</span><span class="p">)</span> <span class="o">:</span> <span class="nx">int32</span>
<span class="nx">header</span> <span class="s2">&#34;foobar.h&#34;</span><span class="p">;</span>
<span class="kr">native</span> <span class="nx">checked</span> <span class="nx">fn</span> <span class="nx">foobarWithRef</span><span class="p">(</span><span class="nx">ref</span> <span class="o">:</span> <span class="o">&amp;</span><span class="nx">int32</span><span class="p">)</span> <span class="o">:</span> <span class="nx">int32</span>
<span class="nx">header</span> <span class="s2">&#34;foobar.h&#34;</span><span class="p">;</span>
<span class="kr">native</span> <span class="nx">checked</span> <span class="nx">fn</span> <span class="nx">foobarVoid</span><span class="p">(</span><span class="nx">n</span> : <span class="kt">int32</span><span class="p">)</span> <span class="o">:</span> <span class="k">void</span>
<span class="nx">header</span> <span class="s2">&#34;foobar.h&#34;</span><span class="p">;</span></code></pre></div>
<p>expects <code>foobar.h</code> to look something like</p>
<div class="highlight"><pre class="chroma"><code class="language-C" data-lang="C"><span class="cp">#include</span> <span class="cpf">&lt;BCDS_Basics.h&gt;</span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf">&lt;BCDS_Retcode.h&gt;</span><span class="cp">
</span><span class="cp">#include</span> <span class="cpf">&lt;stdint.h&gt;</span><span class="cp">
</span><span class="cp"></span>
<span class="n">Retcode_T</span> <span class="nf">foobar</span><span class="p">(</span><span class="n">int32_t</span><span class="o">*</span> <span class="n">result</span><span class="p">,</span> <span class="n">int32_t</span> <span class="n">n</span><span class="p">);</span>
<span class="n">Retcode_T</span> <span class="nf">foobarWithRef</span><span class="p">(</span><span class="n">int32_t</span><span class="o">*</span> <span class="n">result</span><span class="p">,</span> <span class="n">int32_t</span><span class="o">*</span> <span class="n">ref</span><span class="p">);</span>
<span class="n">Retcode_T</span> <span class="nf">foobarVoid</span><span class="p">(</span><span class="kt">void</span><span class="o">*</span> <span class="n">result</span><span class="p">,</span> <span class="n">int32_t</span><span class="o">*</span> <span class="n">ref</span><span class="p">);</span></code></pre></div>
<p>The <code>Retcode_T</code> and <code>BCDS_*</code> includes are specific to the <a href="../../platforms/xdk110/">XDK110 platform</a>.
Other platforms will use a different type to express error codes.</p>
<h2 id="custom-c-file-include">Custom C file include</h2>
<p>The Makefile of an Mita project is automatically generated. The compiler will include all C files and header in your project in that
Makefile. This way you can mix C and Mita code within the same project.
For example you could have a custom header and corresponding implementation in your project, and an Mita file which declares them.</p>
<p><img src="ffiExample.png" alt="Using custom C code" /></p>
<h2 id="pitfalls">Pitfalls</h2>
<p>In order to support all features of Mita, we sometimes have to generate code which does not directly map to a &ldquo;native C API&rdquo;.
Arrays are a good example: each array type in Mita gets its corresponding C type. For example <code>array&lt;int32&gt;</code> turns into an <code>array_int32</code> structure and not <code>int32_t[]</code> as one could expect.</p>
<p>Whenever you cannot import an existing API directly using <code>unchecked</code> native functions, you could write a wrapper in C using custom C file includes described above.</p>
<aside class="copyright" role="note">
&copy; 2018 The Eclipse Mita Project &ndash;
Documentation built with
<a href="https://www.gohugo.io" target="_blank">Hugo</a>
using the
<a href="http://github.com/digitalcraftsman/hugo-material-docs" target="_blank">Material</a> theme.
</aside>
<footer class="footer">
<nav class="pagination" aria-label="Footer">
<div class="previous">
<a href="../../platforms/xdk110/" title="XDK110">
<span class="direction">
Previous
</span>
<div class="page">
<div class="button button-previous" role="button" aria-label="Previous">
<i class="icon icon-back"></i>
</div>
<div class="stretch">
<div class="title">
XDK110
</div>
</div>
</div>
</a>
</div>
<div class="next">
<a href="../../language/events/" title="Events">
<span class="direction">
Next
</span>
<div class="page">
<div class="stretch">
<div class="title">
Events
</div>
</div>
<div class="button button-next" role="button" aria-label="Next">
<i class="icon icon-forward"></i>
</div>
</div>
</a>
</div>
</nav>
</footer>
</div>
</article>
<div class="results" role="status" aria-live="polite">
<div class="scrollable">
<div class="wrapper">
<div class="meta"></div>
<div class="list"></div>
</div>
</div>
</div>
</main>
<script>
var base_url = '';
var repo_id = '';
</script>
<script src="../../javascripts/application.js"></script>
<script>
/* Add headers to scrollspy */
var headers = document.getElementsByTagName("h2");
var scrollspy = document.getElementById('scrollspy');
if(scrollspy) {
if(headers.length > 0) {
for(var i = 0; i < headers.length; i++) {
var li = document.createElement("li");
li.setAttribute("class", "anchor");
var a = document.createElement("a");
a.setAttribute("href", "#" + headers[i].id);
a.setAttribute("title", headers[i].innerHTML);
a.innerHTML = headers[i].innerHTML;
li.appendChild(a)
scrollspy.appendChild(li);
}
} else {
scrollspy.parentElement.removeChild(scrollspy)
}
/* Add permanent link next to the headers */
var headers = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
for(var i = 0; i < headers.length; i++) {
var a = document.createElement("a");
a.setAttribute("class", "headerlink");
a.setAttribute("href", "#" + headers[i].id);
a.setAttribute("title", "Permanent link")
a.innerHTML = "#";
headers[i].appendChild(a);
}
}
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.8.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>