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 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<TITLE>IMPORT Foreign Function Import
</TITLE>
</HEAD>
<BODY>
<H2>IMPORT Foreign Function Import
</H2>
<P>
Section: <A HREF=sec_external.html> FreeMat External Interface </A>
<H3>Usage</H3>
The import function allows you to call functions that are compiled into
shared libraries, as if they were FreeMat functions. The usage is
<PRE>
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:
<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>
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:
<PRE>
type[optional bounds check] {optional &}name
</PRE>
<P>
Here is a list of various scenarios (expressed in 'C'), and the corresponding
entries, along with snippets of code.
\emph{Scalar variable passed by value:}
Suppose a function is defined in the library as
<PRE>
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
<PRE>
'float t'
</PRE>
<P>
For a C-string, which corresponds to a function prototype of
<PRE>
int fooFunction(const char *t),
</PRE>
<P>
the corresponding argument string would be
<PRE>
'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.
\emph{Scalar variable passed by reference:}
Suppose a function is defined in the library as
<PRE>
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
<PRE>
'float &t'
</PRE>
<P>
If the function <code>fooFunction</code> modifies <code>t</code>, then the argument
passed in FreeMat will also be modified.
\emph{Array variable passed by value:}
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
<PRE>
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
<PRE>
'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 $N \times N$
matrix to the following function:
<PRE>
float determinantmatrix(int N, float *A),
</PRE>
<P>
we can use the following argument to <code>import</code>:
<PRE>
'int32 N, float[N*N] t'.
</PRE>
<P>
\emph{Array variable passed by reference:}
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 $x.^2$):
<PRE>
void squarearray(int N, float *A)
</PRE>
<P>
we can use the following argument to <code>import</code>:
<PRE>
'int32 N, float[N] &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.
\emph{Sending text to the FreeMat console:}
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:
<PRE>
/* 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.
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.
<H3>Example</H3>
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>
addArrays.c
void addArrays(int N, float *a, float *b, float *c) {
int i;
for (i=0;i<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:
<PRE>
import('add.so','addArrays','addArrays','void', ...
'int32 N, float[N] a, float[N] b, float[N] &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:
<PRE>
--> if (strcmp(computer,'MAC')) system('gcc -bundle -flat_namespace -undefined suppress -o add.so addArrays.c'); end;
--> if (~strcmp(computer,'MAC')) system('gcc -shared -fPIC -o add.so addArrays.c'); end;
--> import('add.so','addArrays','addArrays','void','int32 N, float[N] a, float[N] b, float[N] &c');
--> a = [3,2,3,1];
--> b = [5,6,0,2];
--> c = [0,0,0,0];
--> addArrays(length(a),a,b,c)
ans =
[]
--> c
ans =
8 8 3 3
</PRE>
<P>
</BODY>
</HTML>
|