## 6.2.2 Example

Let us consider an example given in examples/interface-tutorial.

We have the following C function `matmul` which performs a matrix multiplication. Only the calling sequence is important.

```/*Matrix multiplication C=A*B, (A,B,C stored columnwise) */

#define A(i,k) a[i + k*n]
#define B(k,j) b[k + j*m]
#define C(i,j) c[i + j*n]

void matmul(a,n,m,b,l,c)
double a[],b[],c[];
int n,m,l;
{
int i,j,k; double s;
for( i=0 ; i < n; i++)
{
for( j=0; j < l; j++)
{
s = 0.;
for( k=0; k< m; k++)
{
s += A(i,k)*B(k,j);
}
C(i,j) = s;
}
}
}
```

We want to have a new Scilab function (also called `matmul`) which is such that the Scilab command

```-->C=matmul(A,B)
```
returns in `C` the matrix product `A*B` computed by the above C function. Here `A, B` and `C` are standard numeric Scilab matrices. Thus, the Scilab matrices `A` and `B` should be sent to the C function `matmul` and the matrix `C` should be created, filled, and sent back to Scilab.

To create the Scilab function `matmul`, we have to write the following C gateway function called `intmatmul`. See the file
`SCIDIR/examples/interface-tutorial/intmatmul.c`.

```#include "stack-c.h"

int intmatmul(fname)
char *fname;
{
static int l1, m1, n1, l2, m2, n2, l3;
static int minlhs=1, maxlhs=1, minrhs=2, maxrhs=2;

/* Check number of inputs (Rhs=2) and outputs (Lhs=1) */
CheckRhs(minrhs,maxrhs) ; CheckLhs(minlhs,maxlhs) ;

/* Get A (#1) and B (#2) as double ("d") */
GetRhsVar(1, "d", &m1, &n1, &l1);
GetRhsVar(2, "d", &m2, &n2, &l2);

/* Check dimensions    */
if (!(n1==m2)) {Scierror(999,"%s: Uncompatible dimensions\r\n",fname);
return 0;}

/* Create C (#3) as double ("d") with m1 rows and n1 columns */
CreateVar(3, "d", &m1, &n2, &l3);

/* Call the multiplication function matmul
inputs:stk(l1)->A, stk(l2)->B  output:stk(l3)->C    */
matmul(stk(l1), m1, n1, stk(l2), n2, stk(l3));

/*  Return C (3)  */
LhsVar(1) = 3;
return 0;
}
```

Let us now explain each step of the gateway function `intmatmul`. The gateway function must include the file `SCIDIR/routines/stack-c.h`. This is the first line of the file. The name of the routine is `intmatmul` and it admits one input parameter which is `fname`. `fname` must be declared as `char *`. The name of the gateway routine (here `intmatmul`) is arbitrary but the parameter `fname` is compulsory. The gateway routine then includes the declarations of the C variables used. In the gateway function `intmatmul` the Scilab matrices `A`, `B` and `C` are referred to as numbers, respectively `1`, `2` and `3`.

The line

```CheckRhs(minrhs,maxrhs); CheckLhs(minlhs,maxlhs);
```
is to check that the Scilab function `matmul` is called with a correct number of RHS and LHS parameters. For instance, typing `-->matmul(A)` will give an error message made by `CheckRhs`. The function `CheckRhs` just compares the C variable `Rhs` (transmitted in the include file `stack-c.h`) with the bounds `minrhs` and `maxrhs`.

The next step is to deal with the Scilab variables `A`, `B` and `C`. In a gateway function, all the Scilab variables are referred to as numbers. Here, the Scilab matrices `A`, `B` and `C` are respectively numbered `1`, `2` and `3`. Each input variable of the newly created Scilab function `matmul` (i.e. `A` and `B`) should be processed by a call to `GetRhsVar`. The first two parameters of `GetRhsVar` are inputs and the last three parameters are outputs. The line

```GetRhsVar(1, "d", &m1, &n1, &l1);
```
means that we process the RHS variable numbered `1` (i.e. `A`). The first parameter of `GetRhsVar` (here `1`) refers to the first parameter (here `A`) of the Scilab function `matmul`. This variable is a Scilab numeric matrix which should be seen ("d") as a `double` C array, since the C routine `matmul` is expecting a `double` array. The second parameter of `GetRhsVar` (here `"d"`) refers to the type (double, int, char etc) of the variable. From the call to `GetRhsVar` we know that `A` has `m1` rows and `n1` columns.

The line

```if (n1 !=m2 )
{Scierror(999,"%s: Uncompatible dimensions\r\n",fname);
return 0;}
```
is to make a return to Scilab if the matrices `A` and `B` passed to `matmul` have uncompatible dimensions. The number of columns of `A` should be equal to the number of rows of `B`.

The next step is to create the output variable `C`. This is done by

```CreateVar(3, "d", &m1, &n2, &l3);
```
Here we create a variable numbered `3` (`1` was for `A` and `2` was for `B`). It is an array of double (`"d"`). It has `m1` rows and `n2` columns. The calling sequence of `CreateVar` is the same as the calling sequence of `GetRhsVar`, but the four first parameters of `CreateVar` are inputs.

The next step is the call to `matmul`. Remember the calling sequence :

```void matmul(a,n,m,b,l,c)
double a[],b[],c[]; int n,m,l;
```
We must send to this function (double) pointers to the numeric data in `A`, `B` and `C`. This is done by :
```  matmul(stk(l1), m1, n1, stk(l2), n2, stk(l3));
```
Here `stk(l1)` is a double pointer to the content of the `A` matrix. The entries of the `A` matrix are stored columnwise in `stk(l1)[0]`, `stk(l1)[1]` etc. Similarly, after the call to the C function `matmul` the (double) numbers `stk(l3)[0]`, `stk(l3)[1]` are the values of the matrix product `A*B` stored columnwise as computed by `matmul`. The last parameter of the functions `GetRhsVar` and `CreateVar` is an output parameter which allow to access the data through a pointer (here the double pointers `stk(l1)`, `stk(l2)` and `stk(l3)`.

The final step is to return the result, i.e. the `C` matrix to Scilab. This is done by

```  LhsVar(1) = 3;
```
This statement means that the first LHS variable of the Scilab function `matmul` is the variable numbered `3`.

Once the gateway routine is written, it should be compiled, linked with Scilab and a script file should be executed in Scilab for loading the new function.

It is possible to build a static or a dynamic library. The static library corresponding the the example just described here is built in the directory `SCIDIR/examples/interface-tutorial` and the dynamic library is built into the directory `SCIDIR/examples/interface-tutorial-so`.

Sous-sections