Please note that the recommended version of Scilab is 2024.1.0. This page might be outdated.
However, this page did not exist in the previous stable version.
How to deal with optional parameters
how to deal with optional parameters send to an interface 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 set of optional parameters via a C gateway and then to perform some checks in the C function (number of optional parameters, does an optional parameters exists, etc.).
This example is available in the directory core/examples/optional_parameters
The C function
#include <stack-c.h> int ex2c(double * a, int * ma, int * na, double * b, int * mb, int * nb) { int i; for(i=0;i<(*ma)*(*na);i++) a[i] = 2*a[i]; for(i=0;i<(*mb)*(*nb);i++) b[i] = 3*b[i]; return(0); } int sci_optional_parameters(char * fname) { int m1,n1,l1; // optional names must be stored in alphabetical order in opts static rhs_opts opts[]= {{-1,"v1","d",0,0,0}, {-1,"v2","d",0,0,0}, {-1,NULL,NULL,0,0}}; int minrhs = 1, maxrhs = 1; int minlhs = 1, maxlhs = 3; int nopt, iopos, res; char buffer_name[csiz]; // csiz used for character coding nopt = NumOpt(); CheckRhs(minrhs,maxrhs+nopt); CheckLhs(minlhs,maxlhs); // first non optional argument GetRhsVar( 1, "c", &m1, &n1, &l1); if (get_optionals(fname,opts)==0) return 0; // default values if optional arguments are not given: v1=[99] and v2=[3] sciprint("number of optional parameters = %d\n", NumOpt()); sciprint("first optional parameters = %d\n", FirstOpt()); sciprint("FindOpt(v1) = %d\n", FindOpt("v1", opts)); sciprint("FindOpt(v2) = %d\n", FindOpt("v2", opts)); if (IsOpt(1,buffer_name)) sciprint("parameter 1 is optional: %s\n", buffer_name); if (IsOpt(2,buffer_name)) sciprint("parameter 2 is optional: %s\n", buffer_name); if (IsOpt(3,buffer_name)) sciprint("parameter 3 is optional: %s\n", buffer_name); iopos = Rhs; if (opts[0].position==-1) { iopos++; opts[0].position = iopos; opts[0].m = 1; opts[0].n = 1; opts[0].type = "d"; CreateVar(opts[0].position, opts[0].type, &opts[0].m, &opts[0].n, &opts[0].l); *stk(opts[0].l) = 99.0; } if (opts[1].position==-1) { iopos++ ; opts[1].position = iopos; opts[1].m = 1; opts[1].n = 1; opts[1].type = "d"; CreateVar(opts[1].position, opts[1].type, &opts[1].m, &opts[1].n, &opts[1].l); *stk(opts[1].l) = 3; } ex2c(stk(opts[0].l),&opts[0].m,&opts[0].n, stk(opts[1].l),&opts[1].m,&opts[1].n); // return the first argument (unchanged ) then v1 and v2 LhsVar(1) = 1; LhsVar(2) = opts[0].position; LhsVar(3) = opts[1].position; return 0; }
This file must be saved as "optional_parameters.c".
The main thing to highlight is that, to build a C interface function, we need to include the header stack-c.h. In this header, we find the prototypes and macros of the main C interface functions. We also need to include sciprint.h because we use the sciprint function.
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 builder script
// This is the builder.sce // must be run from this directory lines(0); ilib_name = 'lib_optional_parameters'; files = ['optional_parameters.c']; libs = []; table =['optional_parameters', 'sci_optional_parameters']; 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 optional_parameters.c), what will be the name of the shared library (here, it's lib_optional_parameters) and which C symbol will be linked to a Scilab function (here, we will link the sci_optional_parameters C symbol to the Scilab function "optional_parameters").
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.
Testing our new function
We now write a simple example to test our new functions.
// Example with optional argument specified with the 'arg=value syntax' // [a,b,c] = ex12c(x1, [v1 = arg1, v2 = arg2]), arg1 default value 99 // arg2 default value 3 // only v1 and v2 are recognized as optional argument names // the return value are a = x1, b = 2*v2, c = 3*v2 [a,b,c] = optional_parameters('test'); disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c)); [a,b,c] = optional_parameters('test',v1=[10,20]); disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c)); [a,b,c] = optional_parameters('test',v1=[10,20],v2=8); disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c)); [a,b,c] = optional_parameters('test',v2=8,v1=[10]); disp('a = ' + a + ' b = ' + string(b) + ' c = ' + string(c));
The script must be saved as "optional_parameters.sce".
Let's run our scripts and see what is the result:
-->;exec builder.sce; Génère un fichier gateway Génère un fichier loader Génère un Makefile : Makelib Exécute le makefile Compilation de optional_parameters.c Construction de la bibliothèque partagée (soyez patient) -->;exec loader.sce; Bibliothèque partagée chargée. Link done. -->;exec optional_parameters.sce; number of optional parameters = 0 first optional parameters = 2 FindOpt(v1) = 0 FindOpt(v2) = 0 a = test b = 198 c = 9 number of optional parameters = 1 first optional parameters = 2 FindOpt(v1) = 2 FindOpt(v2) = 0 parameter 2 is optional: v1 !a = test b = 20 c = 9 a = test b = 40 c = 9 ! number of optional parameters = 2 first optional parameters = 2 FindOpt(v1) = 2 FindOpt(v2) = 3 parameter 2 is optional: v1 parameter 3 is optional: v2 !a = test b = 20 c = 24 a = test b = 40 c = 24 ! number of optional parameters = 2 first optional parameters = 2 FindOpt(v1) = 3 FindOpt(v2) = 2 parameter 2 is optional: v2 parameter 3 is optional: v1 a = test b = 20 c = 24
See Also
<< How to create and access a list | How to | CheckColumn >> |