File: external_import.html

package info (click to toggle)
freemat 4.2%2Bdfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 141,800 kB
  • ctags: 14,082
  • sloc: ansic: 126,788; cpp: 62,046; python: 2,080; perl: 1,255; sh: 1,146; yacc: 1,019; lex: 239; makefile: 100
file content (180 lines) | stat: -rw-r--r-- 10,838 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>FreeMat: IMPORT Foreign Function Import</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">FreeMat
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.1.1 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li class="current"><a href="pages.html"><span>Related&#160;Pages</span></a></li>
    </ul>
  </div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('external_import.html','');});
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<div class="title">IMPORT Foreign Function Import </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>Section: <a class="el" href="sec_external.html">FreeMat External Interface</a> </p>
<h1><a class="anchor" id="Usage"></a>
Usage</h1>
<p>The import function allows you to call functions that are compiled into shared libraries, as if they were FreeMat functions. The usage is </p>
<pre class="fragment">  import(libraryname,symbol,function,return,arguments)
</pre><p> The argument <code>libraryname</code> is the name of the library (as a string) to import the function from. The second argument <code>symbol</code> (also a string), is the name of the symbol to import from the library. The third argument <code>function</code> is the the name of the function after its been imported into Freemat. The fourth argument is a string that specifies the return type of the function. It can take on one of the following types: </p>
<ul>
<li>
'uint8' for an unsigned, 8-bit integer.  </li>
<li>
'int8' for a signed, 8-bit integer.  </li>
<li>
'uint16' an unsigned, 16-bit integer.  </li>
<li>
'int16' a signed, 16-bit integer.  </li>
<li>
'uint32' for an unsigned, 32-bit integer.  </li>
<li>
'int32' for a signed, 32-bit integer.  </li>
<li>
'single' for a 32-bit floating point.  </li>
<li>
'double' for a 64-bit floating point.  </li>
<li>
'void' for no return type.  </li>
</ul>
<p>The fourth argument is more complicated. It encodes the arguments of the imported function using a special syntax. In general, the argument list is a string consisting of entries of the form:</p>
<pre class="fragment">  type[optional bounds check] {optional &amp;}name
</pre><p>Here is a list of various scenarios (expressed in 'C'), and the corresponding entries, along with snippets of code.</p>
<h2>Scalar variable passed by value</h2>
<p>Suppose a function is defined in the library as </p>
<pre class="fragment">  int fooFunction(float t),
</pre><p> i.e., it takes a scalar value (or a string) that is passed by value. Then the corresponding argument string would be </p>
<pre class="fragment">  'float t'
</pre><p> For a C-string, which corresponds to a function prototype of </p>
<pre class="fragment">  int fooFunction(const char *t),
</pre><p> the corresponding argument string would be </p>
<pre class="fragment">  'string t'
</pre><p> Other types are as listed above. Note that FreeMat will automatically promote the type of scalar variables to the type expected by the <code>C</code> function. For example, if we call a function expecting a <code>float</code> with a <code>double</code> or <code>int16</code> argument, then FreeMat will automatically apply type promotion rules prior to calling the function.</p>
<h2>Scalar variable passed by reference:</h2>
<p>Suppose a function is defined in the library as </p>
<pre class="fragment">  int fooFunction(float *t),
</pre><p> i.e., it takes a scalar value (or a string) that is passed as a pointer. Then the corresponding argument string would be </p>
<pre class="fragment">  'float &amp;t'
</pre><p> If the function <code>fooFunction</code> modifies <code>t</code>, then the argument passed in FreeMat will also be modified.</p>
<h2>Array variable passed by value:</h2>
<p>In <code>C</code>, it is impossible to distinguish an array being passed from a simple pointer being passed. More often than not, another argument indicates the length of the array. FreeMat has the ability to perform bounds-checking on array values. For example, suppose we have a function of the form </p>
<pre class="fragment">  int sum_onehundred_ints(int *t),
</pre><p> where <code>sum_onehundred_ints</code> assumes that <code>t</code> is a length <code>100</code> vector. Then the corresponding FreeMat argument is </p>
<pre class="fragment">  'float32[100] t'.
</pre><p> Note that because the argument is marked as not being passed by reference, that if <code>sub_onehundred_ints</code> modifies the array <code>t</code>, this will not affect the FreeMat argument. Note that the bounds-check expression can be any legal scalar expression that evaluates to an integer, and can be a function of the arguments. For example to pass a square <img class="formulaInl" alt="$N \times N$" src="form_30.png"/> matrix to the following function: </p>
<pre class="fragment">  float determinantmatrix(int N, float *A),
</pre><p> we can use the following argument to <code>import</code>: </p>
<pre class="fragment">  'int32 N, float[N*N] t'.
</pre><h2>Array variable passed by reference:</h2>
<p>If the function in <code>C</code> modifies an array, and we wish this to be reflected in the FreeMat side, we must pass that argument by reference. Hence, consider the following hypothetical function that squares the elements of an array (functionally equivalent to <img class="formulaInl" alt="$x.^2$" src="form_31.png"/>): </p>
<pre class="fragment">  void squarearray(int N, float *A)
</pre><p> we can use the following argument to <code>import</code>: </p>
<pre class="fragment">  'int32 N, float[N] &amp;A'.
</pre><p> Note that to avoid problems with memory allocation, external functions are not allowed to return pointers. As a result, as a general operating mechanism, the FreeMat code must allocate the proper arrays, and then pass them by reference to the external function.</p>
<h2>Sending text to the FreeMat console:</h2>
<p>Starting with FreeMat 4.0, it is possible for external code that is called using the <code>import</code> statement to send text to the FreeMat console. To do so, you must define in each library that wants to send text a function with the name <code>freemat_io_handler</code> that captures its argument (a function pointer), and stores it for use by functions in the library. That function pointer takes a standard C string argument. Here is a snippet of code to demonstrate how this works: </p>
<pre class="fragment">  /* just to make it readable */
  typedef void (*strfunc)(const char*); 

  /* The name we want to use for the function */
  strfunc FreeMatText;                  

  /* this name is case sensitive and must not be mangled (i.e., use extern "C") */
  void freemat_io_handler(strfunc printFunc) {
     FreeMatText = printFunc;
  }

  double SomeImportedFunction(double t) {
     FreeMatText("I am going to double that argument!\n");
     return (t*2);
  }
</pre><p> In this case, once <code>SomeImportedFunction</code> is called from within FreeMat, the text <code>"I am going to double that argument"</code> will appear in the FreeMat console.</p>
<p>Your <code>freemat_io_handler</code> function is automatically called when your library is loaded by FreeMat, which happens with the first <code>import</code> statement that references it.</p>
<p>Repeating <code>import</code> calls to import the same function name will be ignored, except the first call. In order to refresh the function without restarting FreeMat, you have to first clear all imported libraries via: </p>
<pre class="fragment">   clear 'libs'
</pre><h1><a class="anchor" id="Example"></a>
Example</h1>
<p>Here is a complete example. We have a <code>C</code> function that adds two float vectors of the same length, and stores the result in a third array that is modified by the function. First, the <code>C</code> code:</p>
<pre class="fragment">     addArrays.c
</pre><pre class="fragment">void addArrays(int N, float *a, float *b, float *c) {
  int i;
 
  for (i=0;i&lt;N;i++)
   c[i] = a[i] + b[i];
}
</pre><p>We then compile this into a dynamic library, say, <code>add.so</code>. The import command would then be: </p>
<pre class="fragment">  import('add.so','addArrays','addArrays','void', ...
         'int32 N, float[N] a, float[N] b, float[N] &amp;c');
</pre><p> We could then exercise the function exactly as if it had been written in FreeMat. The following only works on systems using the GNU C Compiler:</p>
<pre class="fragment">--&gt; if (strcmp(computer,'MAC')) system('gcc -bundle -flat_namespace -undefined suppress -o add.so addArrays.c'); end;
--&gt; if (~strcmp(computer,'MAC')) system('gcc -shared -fPIC -o add.so addArrays.c'); end;
--&gt; import('add.so','addArrays','addArrays','void','int32 N, float[N] a, float[N] b, float[N] &amp;c');
--&gt; a = [3,2,3,1];
--&gt; b = [5,6,0,2]; 
--&gt; c = [0,0,0,0];
--&gt; addArrays(length(a),a,b,c)

ans = 
  []
--&gt; c

ans = 
 8 8 3 3 
</pre> </div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="navelem"><a class="el" href="index.html">FreeMat Documentation</a></li><li class="navelem"><a class="el" href="sec_external.html">FreeMat External Interface</a></li>
    <li class="footer">Generated on Thu Jul 25 2013 18:58:17 for FreeMat by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.1.1 </li>
  </ul>
</div>
</body>
</html>