Scilab Website | Contribute with GitLab | Mailing list archives | ATOMS toolboxes
Scilab Online Help
5.3.0 - Português

Change language to:
English - Français - 日本語 -

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.

Manual Scilab >> API Scilab > Scilab Gateway API > How to > How to create and access a list

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:

exec builder.sce;
exec loader.sce;

A = mlist(['mytype','var1','var2'],'a string',[1 2; 3 4]);
 
print_list(A);

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:

exec builder.sce;
exec loader.sce;

A = create_list();
 
disp(typeof(A))
disp(getfield(1,A))
disp(A('var1'))
disp(A('var2'))
<< How to check parameters How to How to deal with optional parameters >>

Copyright (c) 2022-2024 (Dassault Systèmes)
Copyright (c) 2017-2022 (ESI Group)
Copyright (c) 2011-2017 (Scilab Enterprises)
Copyright (c) 1989-2012 (INRIA)
Copyright (c) 1989-2007 (ENPC)
with contributors
Last updated:
Wed Jan 26 16:24:43 CET 2011