swig/Doc/Manual/Scilab.html
Baozeng Ding 153ffe45af update the Doc
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-sploving@12001 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2010-04-30 02:16:56 +00:00

493 lines
13 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>36 SWIG and Scilab</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Scilab_nn2">Preliminaries</a>
<li><a href="#Scilab_nn3">Running SWIG</a>
<ul>
<li><a href="#Scilab_nn5">Compiling a dynamic module</a>
<li><a href="#Scilab_nn6">Using your module</a>
</ul>
<li><a href="#Scilab_nn7">A tour of basic C/C++ wrapping</a>
<ul>
<li><a href="#Scilab_nn8">Modules</a>
<li><a href="#Scilab_nn9">Functions</a>
<li><a href="#scilab_nn10">Global variables</a>
<li><a href="#Scilab_nn11">Constants</a>
<li><a href="#Scilab_nn12">Enums</a>
<li><a href="#Scilab_nn13">Pointers</a>
<li><a href="#Scilab_nn14">Structs</a>
<li><a href="#Scilab_nn15">Arrays</a>
<li><a href="#Scilab_nn16">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 do 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_nn2"></a>36.1 Preliminaries</H2>
<p>
The current SWIG implemention is based on Scilab 5.2.2. Support for other higher versions has not been tested, nor has support for any OS other than Linux.
</p>
<H2><a name="Scilab_nn3"></a>36.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 an 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_nn5"></a>36.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>--&gt; exec loader.sce</pre></div>
<H3><a name="Scilab_nn6"></a>36.2.2 Using your module</H3>
<p>
Assuming all goes well, you will be able to do this:
<br>
</p>
<div class="targetlang"><pre>
--&gt; gcd(4,6)
ans = 2
--&gt; Foo_get
ans = 3
--&gt; Foo_set(4);
--&gt; Foo_get
ans = 4 </pre></div>
<H2><a name="Scilab_nn7"></a>36.3 A tour of basic C wrapping</H2>
<H3><a name="Scilab_nn8"></a>36.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 could use the module.
</pre>
<H3><a name="Scilab_nn9"></a>36.3.2 Functions</H3>
<p>
Global functions are wrapped as new Scilab built-in functions. For example,
</p>
<div class="code"><pre>&#037;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>--&gt; fact(4)
ans=24 </pre></div>
<H3><a name="scilab_nn10"></a>36.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 variables onto the C variable.
</p>
<div class="targetlang"><pre>--&gt; exec loader.sce;
--&gt; c=Foo_get();
--&gt; Foo_set(4);
--&gt; c
c = 3
--&gt; Foo_get()
ans = 4
</pre></div>
<H3><a name="Scilab_nn11"></a>36.3.4 Constants</H3>
<p>
C constants are not really constant in Scilab. When dealing with the constants, the 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>
--&gt; exec loader.sce;
--&gt; ICONST_get();
ans= 42
--&gt; FCONST_get();
ans= 2.1828
--&gt; CCONST_get();
ans=x
--&gt; CCONST2_get();
ans=
--&gt; SCONST_get();
ans= Hello World
--&gt; SCONST2_get();
ans= "Hello World"
--&gt; EXPR_get();
ans= 48.5484
--&gt; iconst_get();
ans= 37
--&gt; fconst_get();
ans= 3.14
</pre></div>
<H3><a name="Scilab_nn12"></a>36.3.5 Enums</H3>
<p> The way that deals with the enums is similar to the 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. So it could be used as the following:
</p>
<div class="targetlang"><pre>
--&gt; exec loader.sce;
--&gt; printf(" RED = %i\n", RED_get());
RED = 0
--&gt; printf(" BLUE = %i\n", BLUE_get());
BLUE = 1
--&gt; printf(" GREEN = %i\n", GREEN_get());
GREEN = 2
</pre></div>
<H3><a name="Scilab_nn13"></a>36.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 a 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>
--&gt; r = sub(37,42);
--&gt; printf(" 37 - 42 = %i\n",r);
37 - 42 = -5
--&gt; [q,r] = divide(42,37);
--&gt; 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_nn14"></a>36.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 wrappered, it would generate two main function: Foo_x_set(), which set the data value of the structrure and Foo_x_get() which could obtain the value of the structrure. Run it in Scilab:
</p>
<div class="targetlang"><pre>
--&gt; a=new_Foo();
--&gt; Foo_x_set(a,100);
--&gt; Foo_x_get(a)
ans =
100
</pre></div>
<H3><a name="Scilab_nn15"></a>36.3.8 Arrays</H3>
<p>
Arrays are fully supported by SWIG and Scilab. In SWIG, they are handled as pointers. And Scilab also supports the pointer well. So it is easy to deal with the arrays. 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 wrappered, it would generate the following funtion: x_set(), x_get(), y_set(), y_get(), and _wrap_initArray. So it could be used like this:
</p>
<div class="targetlang"><pre>
--&gt; exec loader.sce
--&gt; initArray();
--&gt; x_get()
ans =
0 1 2 3 4 5 6 7 8 9
--&gt; y_get()
ans =
0. 0.1428571 0.2857143 0.4285714 0.5714286 0.7142857 0.8571429
</pre></div>
<H3><a name="Scilab_nn16"></a>36.3.9 Matrices</H3>
<p>
Scilab uses matrices a lot for numerical mathematics and scientific visualization. So supporting matrices would make 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 wrappered, it would generate the following funtion:
</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>So it could be used like this:
</p>
<div class="targetlang"><pre>
--&gt; exec loader.sce
--&gt; x = new_matrix();
--&gt; for i = 0 : 3;
--&gt; for j = 0 : 3;
--&gt; set_m(x, i, j, i + j);
--&gt; end;
--&gt; end;
--&gt; print_matrix(y);
0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6
--&gt; y = new_matrix();
--&gt; for i = 0 : 3;
--&gt; for j = 0 : 3;
--&gt; set_m(y, i, j, i - j);
--&gt; end;
--&gt; end;
--&gt; print_matrix(y);
0 -1 -2 -3
1 0 -1 -2
2 1 0 -1
3 2 1 0
--&gt; z = new_matrix();
--&gt; mat_mult(x, y, z);
--&gt; print_matrix(z);
14 8 2 -4
20 10 0 -10
26 12 -2 -16
32 14 -4 -22
</pre></div>