595 lines
14 KiB
HTML
595 lines
14 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<title>SWIG and Scilab</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
</head>
|
|
|
|
|
|
<body bgcolor="#ffffff">
|
|
|
|
<H1><a name="Scilab"></a>37 SWIG and Scilab</H1>
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Scilab_preliminaries">Preliminaries</a>
|
|
<li><a href="#Scilab_running">Running SWIG</a>
|
|
<ul>
|
|
<li><a href="#Scilab_compiling_dynamic">Compiling a dynamic module</a>
|
|
<li><a href="#Scilab_using_module">Using your module</a>
|
|
</ul>
|
|
<li><a href="#Scilab_tour_of_basic_c">A tour of basic C wrapping</a>
|
|
<ul>
|
|
<li><a href="#Scilab_modules">Modules</a>
|
|
<li><a href="#Scilab_functions">Functions</a>
|
|
<li><a href="#Scilab_global_variables">Global variables</a>
|
|
<li><a href="#Scilab_constants">Constants</a>
|
|
<li><a href="#Scilab_enums">Enums</a>
|
|
<li><a href="#Scilab_pointers">Pointers</a>
|
|
<li><a href="#Scilab_structs">Structs</a>
|
|
<li><a href="#Scilab_arrays">Arrays</a>
|
|
<li><a href="#Scilab_matrices">Matrices</a>
|
|
</ul>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
<p>
|
|
Scilab is a scientific software package for numerical computations providing a powerful open computing environment for engineering and scientific applications that is mostly compatible with MATLAB. More information can be found at <a href="http://www.scilab.org">www.scilab.org</a>.
|
|
</p>
|
|
|
|
<p>
|
|
This chapter is intended to give an introduction to use the module.
|
|
You should also read the SWIG documentation which is not specific to Scilab.
|
|
Also, there are a dozen or so examples in the Examples/Scilab directory.
|
|
As Scilab doesn't really have objects, so in this module, it supports mainly C features:
|
|
variables, functions, constants, enums, structs, unions, pointers, arrays and matrices.
|
|
</p>
|
|
|
|
<H2><a name="Scilab_preliminaries"></a>37.1 Preliminaries</H2>
|
|
|
|
|
|
<p>
|
|
The current SWIG implemention is based on Scilab 5.2.2. Support for later versions has not been tested, nor has support for any OS other than Linux.
|
|
</p>
|
|
|
|
<H2><a name="Scilab_running"></a>37.2 Running SWIG</H2>
|
|
|
|
|
|
<p>
|
|
Let's start with a very simple SWIG interface file:
|
|
</p>
|
|
|
|
<div class="code"><pre>%module example
|
|
%{
|
|
#include "example.h"
|
|
%}
|
|
int gcd(int x, int y);
|
|
extern double Foo;
|
|
</pre></div>
|
|
|
|
<p>
|
|
To build a Scilab module, run SWIG using the <tt>-scilab</tt> option.
|
|
</p>
|
|
|
|
<div class="shell"><pre>$ swig -scilab example.i </pre></div>
|
|
|
|
<p>
|
|
This creates a C source file <tt>example_wrap.c</tt> and a interface file <tt>builder.sce</tt>. The generated C source file contains the low-level wrappers that need to be compiled and linked with the rest of your C application (in this case, the gcd implementation) to create an extension module. And the builder.sce is used to generate the *.so file.
|
|
</p>
|
|
|
|
<p>
|
|
The swig command line has a number of options you can use, like to redirect it's output. Use <tt>swig --help</tt> to learn about these.
|
|
</p>
|
|
|
|
<H3><a name="Scilab_compiling_dynamic"></a>37.2.1 Compiling a dynamic module</H3>
|
|
|
|
|
|
<p>
|
|
Scilab modules are shared objects having the ".so" suffix.
|
|
Building such a file is usually done with the "exec" command (within Scilab itself) For example,
|
|
</p>
|
|
|
|
<div class="shell"><pre>
|
|
$ ./scilab
|
|
--> exec builder.sce
|
|
</pre></div>
|
|
|
|
<p>
|
|
where builder.sce is the interface file generated by the swig. It looks like the following:
|
|
</p>
|
|
<div class="code"><pre>
|
|
ilib_name = "examplelib";
|
|
files = ["example_wrap.c"];
|
|
libs = [];
|
|
table = ["gcd","_wrap_gcd";"Foo_set","_wrap_Foo_set";"Foo_get","_wrap_Foo_get";];
|
|
ilib_build(ilib_name,table,files,libs);
|
|
</pre></div>
|
|
|
|
<p>ilib_build(lib_name,table,files,libs) is used to create shared libraries and to generate a loader file which can be used to dynamically load the shared library into Scilab with addinter.
|
|
</p>
|
|
|
|
<ul>
|
|
<li><tt><b>ilib_name</b></tt>: a character string, the generic name of the library without path and extension.</li>
|
|
<li><tt><b>files</b></tt>: string matrix giving objects files needed for shared library creation.</li>
|
|
<li><tt><b>libs</b></tt>: string matrix giving extra libraries needed for shred library creation.</li>
|
|
<li><tt><b>table</b></tt>: two column string matrix giving the table of pairs 'scilab-name', 'interface name'.</li>
|
|
</ul>
|
|
|
|
<p>
|
|
"exec builder.sce" will produce *.so,and a file called "loader.sce" which contains how to load the module. Loading it into Scilab is then a matter of invoking
|
|
</p>
|
|
|
|
<div class="shell"><pre>--> exec loader.sce</pre></div>
|
|
|
|
<H3><a name="Scilab_using_module"></a>37.2.2 Using your module</H3>
|
|
|
|
|
|
<p>
|
|
Assuming all goes well, you will be able to do this:
|
|
<br>
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
--> gcd(4,6)
|
|
ans = 2
|
|
|
|
--> Foo_get
|
|
ans = 3
|
|
|
|
--> Foo_set(4);
|
|
|
|
--> Foo_get
|
|
ans = 4 </pre></div>
|
|
|
|
|
|
<H3><a name="Scilab_options"></a>Additional commandline options</H3>
|
|
|
|
<p>
|
|
The following table list the additional commandline options available for the Scilab module. They can also be seen by using:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
swig -scilab -help
|
|
</pre></div>
|
|
|
|
<table summary="Scilab specific options">
|
|
|
|
<tr>
|
|
<th>Scilab specific options</th>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-addcflag <opt></td>
|
|
<td>Additional include options <opt> to include in build script</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-addldflag <opt></td>
|
|
<td>Additional link options <opt> to include in build script</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-addsrc <files></td>
|
|
<td>Additional comma separated source <files> to include in build script</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-vbl <level></td>
|
|
<td>Sets the build verbose <level> (default 0)</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-buildflags <file></td>
|
|
<td>Uses a Scilab script in <file> to set build flags level</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-nobuilder</td>
|
|
<td>Do not generate builder script</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
<p>
|
|
Some examples:
|
|
</p>
|
|
|
|
<div class="shell"><pre>
|
|
$ swig -scilab -addcflag -I/usr/includes example.i
|
|
$ swig -scilab -addldflag -lm example.i
|
|
$ swig -scilab -addsrc file1.cxx file2.cxx example.i
|
|
</pre></div>
|
|
</p>
|
|
|
|
|
|
<H2><a name="Scilab_tour_of_basic_c"></a>37.3 A tour of basic C wrapping</H2>
|
|
|
|
|
|
<H3><a name="Scilab_modules"></a>37.3.1 Modules</H3>
|
|
|
|
|
|
<p>
|
|
The SWIG module directive specifies the name of the Scilab module. If you want to load the module, you'll need a file called "loader.sce" which is usually generated by the command "exec builder.sce". The loader.sce looks as following:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
// ------------------------------------------------------
|
|
// generated by builder.sce: Please do not edit this file
|
|
// ------------------------------------------------------
|
|
|
|
libexamplelib_path = get_file_path('loader.sce');
|
|
list_functions = [ 'gcd';
|
|
'Foo_set';
|
|
'Foo_get';
|
|
];
|
|
addinter(libexamplelib_path+'/libexamplelib.so','libexamplelib',list_functions);
|
|
// remove temp. variables on stack
|
|
clear libexamplelib_path;
|
|
clear list_functions;
|
|
clear get_file_path;
|
|
// ------------------------------------------------------
|
|
</pre></div>
|
|
|
|
<p>addinter (files,spname,fcts) performs dynamic linking of a compiled C new Scilab interface routine.
|
|
</p>
|
|
<ul>
|
|
<li><tt><b>files</b></tt>: a character string or a vector of character string contain object files used to define the new Scilab interface routine (interface code, user routines or libraries, system libraries).</li>
|
|
<li><tt><b>spname</b></tt>: a character string. Name of interface routine entry point.</li>
|
|
<li><tt><b>fcts</b></tt>: vector of character strings. The name of new Scilab function implemented in the new interface.</li>
|
|
</ul>
|
|
|
|
|
|
<p>
|
|
After you run the command "exec loader.sce", you can use the module.
|
|
</pre>
|
|
|
|
<H3><a name="Scilab_functions"></a>37.3.2 Functions</H3>
|
|
|
|
|
|
<p>
|
|
Global functions are wrapped as new Scilab built-in functions. For example,
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
int fact(int n);
|
|
</pre></div>
|
|
|
|
<p>
|
|
creates a built-in function <tt>fact(n)</tt> that works exactly like you think it does:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
--> fact(4)
|
|
ans=24
|
|
</pre></div>
|
|
|
|
<H3><a name="Scilab_global_variables"></a>37.3.3 Global variables</H3>
|
|
|
|
|
|
<p>
|
|
To expose variables, SWIG actually generates two functions, to get and set the value. In this case, Foo_set and Foo_get would be generated. SWIG then automatically calls these functions when you get and set the variable-- in the former case creating a local copy in the interpreter of the C variables, and in the latter case copying an interpreter variable value into the C variable.
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
--> exec loader.sce;
|
|
--> c=Foo_get();
|
|
|
|
--> Foo_set(4);
|
|
|
|
--> c
|
|
c = 3
|
|
|
|
--> Foo_get()
|
|
ans = 4
|
|
</pre></div>
|
|
|
|
<H3><a name="Scilab_constants"></a>37.3.4 Constants</H3>
|
|
|
|
|
|
<p>
|
|
C constants are not really constant in Scilab. When dealing with the constants, a get function will be generated. For example given some constants:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
#define ICONST 42
|
|
#define FCONST 2.1828
|
|
#define CCONST 'x'
|
|
#define CCONST2 '\n'
|
|
#define SCONST "Hello World"
|
|
#define SCONST2 "\"Hello World\""
|
|
</pre></div>
|
|
|
|
<p>It is easy to use them in Scilab:</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
--> exec loader.sce;
|
|
--> ICONST_get();
|
|
ans= 42
|
|
--> FCONST_get();
|
|
ans= 2.1828
|
|
--> CCONST_get();
|
|
ans=x
|
|
--> CCONST2_get();
|
|
ans=
|
|
|
|
--> SCONST_get();
|
|
ans= Hello World
|
|
--> SCONST2_get();
|
|
ans= "Hello World"
|
|
--> EXPR_get();
|
|
ans= 48.5484
|
|
--> iconst_get();
|
|
ans= 37
|
|
--> fconst_get();
|
|
ans= 3.14
|
|
</pre></div>
|
|
|
|
<H3><a name="Scilab_enums"></a>37.3.5 Enums</H3>
|
|
|
|
|
|
<p> The way SWIG deals with the enums is similar to constants. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>%module example
|
|
typedef enum { RED, BLUE, GREEN } color;
|
|
</pre></div>
|
|
|
|
<p>
|
|
Some code like RED_get(), BLUE_get(),GREEN_get() will be generated. It can be used as the following:
|
|
</p>
|
|
|
|
|
|
<div class="targetlang"><pre>
|
|
--> exec loader.sce;
|
|
--> printf(" RED = %i\n", RED_get());
|
|
RED = 0
|
|
|
|
--> printf(" BLUE = %i\n", BLUE_get());
|
|
BLUE = 1
|
|
|
|
--> printf(" GREEN = %i\n", GREEN_get());
|
|
GREEN = 2
|
|
</pre></div>
|
|
|
|
|
|
<H3><a name="Scilab_pointers"></a>37.3.6 Pointers</H3>
|
|
|
|
|
|
<p>
|
|
Pointers are fully supported by SWIG. One way to deal with the pointers is using the INPUT and OUTPUT typemaps. For example, in order to call C functions as the following:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
void sub(int *x, int *y, int *result) {
|
|
*result = *x - *y;
|
|
}
|
|
int divide(int n, int d, int *r) {
|
|
int q;
|
|
q = n/d;
|
|
*r = n - q*d;
|
|
return q;
|
|
}
|
|
</pre></div>
|
|
|
|
<p> We could write an interface file:
|
|
</p>
|
|
|
|
<div class="code"><pre>%module example
|
|
%include typemaps.i
|
|
extern void sub(int *INPUT, int *INPUT, int *OUTPUT);
|
|
|
|
%apply int *OUTPUT { int *r };
|
|
extern int divide(int n, int d, int *r);
|
|
</pre></div>
|
|
|
|
<p>Then run it in Scilab:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
--> r = sub(37,42);
|
|
--> printf(" 37 - 42 = %i\n",r);
|
|
37 - 42 = -5
|
|
|
|
--> [q,r] = divide(42,37);
|
|
--> printf(" 42/37 = %d remainder %d\n",q,r);
|
|
42/37 = 1 remainder 5
|
|
|
|
</pre></div>
|
|
|
|
<p> From the example above, it is clear that instead of passing a pointer to an object,
|
|
we only need a real value instead.
|
|
</p>
|
|
|
|
<H3><a name="Scilab_structs"></a>37.3.7 Structs</H3>
|
|
|
|
|
|
<p>
|
|
SWIG creates a set of accessor functions when encountering a structure or union. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>%module example
|
|
%inline %{
|
|
typedef struct {
|
|
int x;
|
|
} Foo;
|
|
|
|
%}
|
|
</pre></div>
|
|
|
|
<p> When wrapped, it would generate two main function: Foo_x_set(), which set the data value of the structure and Foo_x_get() which could obtain the value of the structure. Run it in Scilab:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
--> a=new_Foo();
|
|
--> Foo_x_set(a,100);
|
|
--> Foo_x_get(a)
|
|
ans =
|
|
|
|
100
|
|
</pre></div>
|
|
|
|
<H3><a name="Scilab_arrays"></a>37.3.8 Arrays</H3>
|
|
|
|
|
|
<p>
|
|
Arrays are fully supported by SWIG and Scilab. In SWIG, they are handled as pointers.
|
|
It is easy to deal with arrays too. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
%module example
|
|
|
|
%inline %{
|
|
int x[10];
|
|
double y[7];
|
|
void initArray()
|
|
{
|
|
int i, n;
|
|
|
|
n = sizeof(x)/sizeof(x[0]);
|
|
for(i = 0; i > n; i++)
|
|
x[i] = i;
|
|
|
|
n = sizeof(y)/sizeof(y[0]);
|
|
for(i = 0; i < n; i++)
|
|
y[i] = ((double) i)/ ((double) n);
|
|
return;
|
|
%}
|
|
</pre></div>
|
|
|
|
<p> When wrapped, the following functions are generated: x_set(), x_get(), y_set(), y_get(), and _wrap_initArray.
|
|
They can be used like this:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
--> exec loader.sce
|
|
|
|
--> initArray();
|
|
--> x_get()
|
|
ans =
|
|
|
|
0 1 2 3 4 5 6 7 8 9
|
|
--> y_get()
|
|
ans =
|
|
|
|
0. 0.1428571 0.2857143 0.4285714 0.5714286 0.7142857 0.8571429
|
|
</pre></div>
|
|
|
|
<H3><a name="Scilab_matrices"></a>37.3.9 Matrices</H3>
|
|
|
|
|
|
<p>
|
|
Scilab uses matrices a lot for numerical mathematics and scientific visualization. Supporting matrices makes Scilab more convenient. For example:
|
|
</p>
|
|
|
|
<div class="code"><pre>%module example
|
|
%inline %{
|
|
double **new_matrix() {
|
|
|
|
int i;
|
|
double **M;
|
|
|
|
M = (double **) malloc(4 * sizeof(double *));
|
|
M[0] = (double *) malloc(16 * sizeof(double));
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
M[i] = M[0] + 4 * i;
|
|
}
|
|
return M;
|
|
}
|
|
|
|
void set_m(double **M, int i, int j, double val) {
|
|
M[i][j] = val;
|
|
}
|
|
|
|
double get_m(double **M, int i, int j) {
|
|
return M[i][j];
|
|
}
|
|
|
|
void print_matrix(double **M) {
|
|
|
|
int i,j;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
for (j = 0; j < 4; j++) {
|
|
printf("%10g ", M[i][j]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
void mat_mult(double **m1, double **m2, double **m3) {
|
|
|
|
int i,j,k;
|
|
double temp[4][4];
|
|
|
|
for (i = 0; i < 4; i++)
|
|
for (j = 0; j < 4; j++) {
|
|
temp[i][j] = 0;
|
|
for (k = 0; k < 4; k++)
|
|
temp[i][j] += m1[i][k] * m2[k][j];
|
|
}
|
|
|
|
for (i = 0; i < 4; i++)
|
|
for (j = 0; j < 4; j++)
|
|
m3[i][j] = temp[i][j];
|
|
}
|
|
%}
|
|
</pre></div>
|
|
|
|
<p> When wrapped, it would generate the following function:
|
|
</p>
|
|
<p>_wrap_new_matrix(): generate a new matrix.
|
|
</p>
|
|
<p>_wrap_set_m(M, i, j, a): set M(i, j) to be value a.
|
|
</p>
|
|
<p>_wrap_get_m(M, i, j): get the value of M(i, j).
|
|
</p>
|
|
<p>_wrap_print_matrix(M): print the matrix M.
|
|
</p>
|
|
<p>_wrap_mat_mult(A, B, C): compute the A * B and the result is stored into C.
|
|
</p>
|
|
<p>It can be used like this:
|
|
</p>
|
|
|
|
<div class="targetlang"><pre>
|
|
--> exec loader.sce
|
|
|
|
--> x = new_matrix();
|
|
--> for i = 0 : 3;
|
|
--> for j = 0 : 3;
|
|
--> set_m(x, i, j, i + j);
|
|
--> end;
|
|
--> end;
|
|
|
|
--> print_matrix(y);
|
|
0 1 2 3
|
|
1 2 3 4
|
|
2 3 4 5
|
|
3 4 5 6
|
|
--> y = new_matrix();
|
|
--> for i = 0 : 3;
|
|
--> for j = 0 : 3;
|
|
--> set_m(y, i, j, i - j);
|
|
--> end;
|
|
--> end;
|
|
|
|
--> print_matrix(y);
|
|
0 -1 -2 -3
|
|
1 0 -1 -2
|
|
2 1 0 -1
|
|
3 2 1 0
|
|
--> z = new_matrix();
|
|
--> mat_mult(x, y, z);
|
|
--> print_matrix(z);
|
|
14 8 2 -4
|
|
20 10 0 -10
|
|
26 12 -2 -16
|
|
32 14 -4 -22
|
|
</pre></div>
|
|
|