6.1.2 Calling a dynamically linked program

The call function can be used to call a dynamically linked program. Consider for example the daxpy Fortran routine. It performs the simple vector operation y=y+a*x or, to be more specific,

y(1)=y(1)+a*x(1), y(1+incy)=y(1+incy)+a*x(1+incx),...
y(1+n*incy)=y(1+n*incy)+a*x(1+n*incx)
where y and x are two real vectors. The calling sequence for daxpy is as follows:
      subroutine daxpy(n,a,x,incx,y,incy)
To call daxpy from Scilab we must use a syntax as follows:
[y1,y2,y3,...]=call('daxpy', inputs description, ...
                    'out', outputs description)
Here inputs description is a set of parameters

x1,p1,t1, x2,p2,t2, x3,p3,t3 ...

where xi is the Scilab variable (real vector or matrix) sent to daxpy, pi is the position number of this variable in the calling sequence of daxpy and ti is the type of xi in daxpy (t='i' t='r' t='d' stands for integer, real or double).

outputs description is a set of parameters

[r1,c1],p1,t1, [r2,c2],p2,t2, [r3,c3],p3,t3,..

which describes each output variable. [ri,ci] is the 2 x 1 integer vector giving the number of rows and columns of the ith output variable yi. pi and ti are as for input variables (they can be omitted if a variable is both input and output).

We see that the arguments of call divided into four groups. The first argument 'daxpy' is the name of the called subroutine. The argument 'out' divides the remaining arguments into two groups. The group of arguments between 'daxpy' and 'out' is the list of input arguments, their positions in the call to daxpy, and their data type. The group of arguments to the right of 'out' are the dimensions of the output variables, their positions in the call to daxpy, and their data type. The possible data types are real, integer, and double precision which are indicated, respectively, by the strings 'r', 'i', and 'd'. Here we calculate y=y+a*x by a call to daxpy (assuming that the link command has been done). We have six input variables x1=n, x2=a, x3=x, x4=incx, x5=y, x6=incy. Variables x1, x4 and x6 are integers and variables x2, x3, x5 are double. There is one output variable y1=y at position p1=5. To simplify, we assume here that x and y have the same length and we take incx=incy=1.

-->a=3;
 
-->x=[1,2,3,4];
 
-->y=[1,1,1,1];
 
-->incx=1;incy=1;

-->n=size(x,'*');

-->y=call('daxpy',...
        n,1,'i',...
        a,2,'d',...
        x,3,'d',...
        incx,4,'i',...
        y,5,'d',...
        incy,6,'i',...
'out',...
        [1,n],5,'d');

 y  =
 
!   4.    7.    10.    13. !
(Since y is both input and output parameter, we could also use the simplified syntax call(...,'out',5) instead of call(...,'out'[1,n],5,'d')).

The same example with the C function daxpy (from CBLAS):

int daxpy(int *n, double *da, double *dx, int *incx, double *dy, int *incy)
...

-->link('daxpy.o','daxpy','C')
linking files daxpy.o  to create a shared executable
Linking daxpy (in fact daxpy)
Link done
 ans  =
 
    1.  

-->y=call('daxpy',...
        n,1,'i',...
        a,2,'d',...
        x,3,'d',...
        incx,4,'i',...
        y,5,'d',...
        incy,6,'i',...
'out',...
        [1,n],5,'d');
 
-->y
 y  =
 
!   4.    7.    10.    13. !

The routines which are linked to Scilab can also access internal Scilab variables: see the examples in given in the examples/links directory.