tratto da qui
Phoenix and Scilab/C Interfacing
August 9th, 2005 ·
As is the case with most instances of foreign function interfacing, your C function
should be `wrapped’ by another function which does all kinds of nitty-gritty
stuff to massage the high-level language datatypes (like lists) to simple C types.
Fortunately, Scilab comes with a program called `intersci’ which creates the
wrapper functions automagically from a text file with some rather simple
interface specifications. Let’s say we wish to write a function which takes in two
numbers and returns its sum. Here is the C function (in a file called add.c):
int add_(int *a, int *b, int *c)
{
*c = *a + *b;
return 0;
}
And here is the interface specification (in a file add_wrap.desc):
add a b
a vector 1
b vector 1
c vector 1
add a b c
a integer
b integer
c integer
out sequence c
The first part of the interface spec specifies what the Scilab function takes as
arguments (a and b, both vectors of length 1). The second part specifies what the
C function takes as arguments (a, b and c, all of which should be pointers to integers,
but which are simply written as `integer’ in the interface spec). The third part says
that `c’ is an output variable, ie, a value `returned’ from the Scilab function.
Note that the address of the object to be returned from the Scilab function is passed as an argument
to the C function. You visualize a Scilab invocation:
c = add(a, b)
getting transformed to a C function invocation of the form:
add(&a, &b, &c);
Here are the steps to make this C function Scilab callable:
- Run the command `intersci-n’ with add_wrap.desc as argument. You should
see several files, two of which are `add_wrap.c’ and `add_wrap_builder.sce’. - Run scilab and type the following at the Scilab prompt:
files = ['add.o', 'add_wrap.o']
libs = []
exec add_wrap_builder.sce
exec loader.sce
Now you can invoke add(1,2) at the Scilab prompt and you will get the proper answer.
(Note that Scilab doesn’t differentiate between a 1 element vector and a scalar
quantity; thus [1] is same as 1).
Adding two vectors
Here is another simple example. Our C function is:
int addvect_(int *n, double *a, double *b, double *c)
{
int i;
for(i = 0; i < *n; i++) c[i] = a[i] + b[i]; return 0; }
The interface spec looks like this:
addvect a b
a vector n
b vector n
c vector n
addvect n a b t
n integer
a double
b double
c double
out sequence c
********************
We can call addvect from the Scilab prompt as shown below:
addvect([1,2,3], [4,5,6])
Returning two vectors
Here is a sample C function:
int addmulvect_(int *n, double *a, double *b, double *c, double *d)
{
int i;
for(i = 0; i < *n; i++) c[i] = a[i] + b[i]; for(i = 0; i < *n; i++) d[i] = a[i] * b[i]; return 0; }
And here is the interface description:
addmulvect a b
a vector n
b vector n
c vector n
d vector n
addmulvect n a b c d
n integer
a double
b double
c double
d double
out sequence c d
The function can be called like this:
[p, q] = addmulvect([1,2,3], [4,5,6])
We note that this function returns two vectors which get stored
in `p’ and `q’.