Please note that the recommended version of Scilab is 2025.0.0. This page might be outdated.
However, this page did not exist in the previous stable version.
How to create and access a list
How to create and access a list using the C gateway functions
Description
WARNING: This API is deprecated from Scilab 5.2.0 and is going to be removed with Scilab 6.0. Please use API Scilab (the new Scilab API).
The goal is to get a [mt]list, to get some elements stored in that this and to send a new [mt]list using a function written in C.
For this, we will wrote two C gateway function in which we will retrieve the [mt]list, and we will create a new [mt]list.
The C function - access to a [mt]list
This example is available in SCI/modules/core/example/print_list.
Let's initialize a mlist in Scilab.
A = mlist(['mytype','var1','var2'],'a string',[1 2; 3 4]);
This mlist is of type 'mytype' (typeof(A)=='mytype') and it has 2 elements:
A('var1') which is equal to 'a string'
A('var2') which is equal to [1 2; 3 4]
We now create a C function called sci_print_list which will print the elements stored in the list.
#include <stack-c.h> #include <sciprint.h> int sci_print_list(char * fname) { int m_list_in, n_list_in, l_list_in; int m_type, n_type; int m_var1, n_var1, l_var1; int m_var2, n_var2, l_var2; char ** LabelList = NULL; CheckRhs(1,1); // We accept only 1 parameter GetRhsVar(1,"m",&m_list_in,&n_list_in,&l_list_in); // Get a mlist // Get the type and the name of the variables (the first element of the mlist) GetListRhsVar(1,1,"S",&m_type,&n_type,&LabelList); if (strcmp(LabelList[0],"mytype")!=0) { sciprint("error, you must ship a mlist or type mytype\n"); return 0; } // Get the first variable (a string) GetListRhsVar(1,2,"c",&m_var1,&n_var1,&l_var1); sciprint("var1 = %s\n",cstk(l_var1)); // Get the second variable (a double matrix) GetListRhsVar(1,3,"d",&m_var2,&n_var2,&l_var2); sciprint("var2 = [%f %f %f %f]\n",*stk(l_var2+0), *stk(l_var2+1), *stk(l_var2+2), *stk(l_var2+3)); return 0; }
To be able to build and link such a C function to scilab, we need to write a Scilab script which will compile this C function and then create a loader script which will link the C function to a Scilab function. The C file is available in the example directory. It is named print_list.c.
The builder script
// This is the builder.sce // must be run from this directory lines(0); ilib_name = 'lib_print_list'; files = ['print_list.c']; libs = []; table =['print_list', 'sci_print_list']; ldflags = ""; cflags = ""; fflags = ""; ilib_build(ilib_name,table,files,libs,'Makelib',ldflags,cflags,fflags); </programlisting> <para>This file must be saved as "builder.sce".</para> <para>This script will tell Scilab which files must be compiled (here, it's print_list.c), what will be the name of the shared library (here, it's lib_print_list) and which C symbol will be linked to a Scilab function (here, we will link the sci_print_list C symbol to the Scilab function "print_list").</para> <para>To build this function, we just need to to:</para> <programlisting role = ""><![CDATA[ exec builder.sce;
Now we are able to test our new C function. First, let's load this new function in scilab:
exec loader.sce;
The script loader.sce is normally automatically built by builder.sce. Let's test our new function:
The C function - creation of a [mt]list
This example is available in SCI/modules/core/example/create_list.
We now write a simple example to test our new function to create a [mt]list.
A = create_list(); disp(A);
First, let's write the C function:
#include <stack-c.h> #include <string.h> int sci_create_list(char * fname) { int m_list_out, n_list_out; int m_var1, n_var1, l_var1, l_list_var1; int m_var2, n_var2, l_var2, l_list_var2; int m_mlist, n_mlist, l_mlist; // The labels of our mlist static const char * ListLabels [] = {"mylist","var1","var2"}; // First, we create the variables using a classical way // The size of the Scilab variables m_var1 = 1; n_var1 = strlen("a string")+1; // a null terminated string m_var2 = 2; n_var2 = 2; // A 2x2 double matrix m_mlist = 3; n_mlist = 1; // A mlist with 3 elements // Creation of the Scilab variables // A('var1') CreateVar(1, "c", &m_var1, &n_var1, &l_var1); // A('var2') CreateVar(2, "d", &m_var2, &n_var2, &l_var2); // A CreateVar(3, "m", &m_mlist, &n_mlist, &l_mlist); // We store values in the create variables // The matrix will be stored in A('var2') *stk(l_var2+0) = 1; *stk(l_var2+1) = 2; *stk(l_var2+2) = 3; *stk(l_var2+3) = 4; // The string will be stored in A('var1') strncpy(cstk(l_var1),"a string\0",n_var1); m_list_out = 3; n_list_out = 1; // now, affect the variable to the mlist // The labels (it corresponds to A = mlist(['mylist','var1','var2'], ... CreateListVarFromPtr(3, 1, "S", &m_list_out, &n_list_out, ListLabels); // The value stored in A('var1') (it corresponds to A = ...,'a string', ... CreateListVarFrom(3, 2, "c", &m_var1, &n_var1, &l_list_var1, &l_var1); // The value stored in A('var2') (it corresponds to A = ...,[1 2,3 4]); CreateListVarFrom(3, 3, "d", &m_var2, &n_var2, &l_list_var2, &l_var2); // We return only the mlist which has been created at position 3 LhsVar(1) = 3; return 0; }
Some important comments related to the CreateVar(Pos,"m",&m, &n, &l) function. When called on a mlist, only the m parameter is taken in account, the n parameter is not used. So, be careful:
m_list = 3; n_list = 1; CreateVar(1, "m", &m_list, &n_list, &l_list);
creates a mlist with 3 elements but:
m_list = 1; n_list = 3; CreateVar(1, "m", &m_list, &n_list, &l_list);
creates a mlist with only 1 element !
Another important thing: when we create a list element using CreateListVarFrom, it is not recommended to access the created variable using, for example, stk(l_list_var2) because CreateListVarFrom performs type transformation on the list variables.
The builder script
// This is the builder.sce // must be run from this directory lines(0); ilib_name = 'lib_create_list'; files = ['create_list.c']; libs = []; table =['create_list', 'sci_create_list']; ldflags = ""; cflags = ""; fflags = ""; ilib_build(ilib_name,table,files,libs,'Makelib',ldflags,cflags,fflags);
This file must be saved as "builder.sce".
This script will tell Scilab which files must be compiled (here, it's create_list.c), what will be the name of the shared library (here, it's lib_create_list) and which C symbol will be linked to a Scilab function (here, we will link the sci_create_list C symbol to the Scilab function "create_list").
To build this function, we just need to to:
exec builder.sce;
Now we are able to test our new C function. First, let's load this new function in scilab:
exec loader.sce;
The script loader.sce is normally automatically built by builder.sce. Let's test our new function:
See Also
- GetRhsVar — a C gateway function which allows to access an argument transmitted to a Scilab function
- GetListRhsVar — a C gateway function which allows to access a parameter stored in a [mt]list transmitted to a Scilab function
- CreateVar — a C gateway function which allows to create a new Scilab parameter
- CreateListVarFrom — a C interface function which allows to create a new Scilab parameter in a [mt]list
- CreateListVarFromPtr — a C interface function which allows to create a new Scilab parameter from a pointer in a [mt]list
- LhsVar — a C gateway function which specifies which parameters created inside the C gateway will be returned as an output argument into Scilab.
- stk — Return a pointer to a double to access data stored at a given position in the Scilab memory
- ilib_build — utility for shared library management
<< How to check parameters | How to | How to deal with optional parameters >> |