Calling a scilab function (macros) from a C interface
When you write a interface with scilab, you can need to call another function directly from your function.
You can pass a pointer on scilab function to your function.
A easy example:
unzip call_scifunction.zip
launch scilab
exec call_scifunction.sce;
v = call_scifunc(30,12,scilabfoo)
you pass a pointer on a scilab function (scilabfoo macro) to your function 'call_scifunc'
C2F(scifunction) calls another scilab function (here scilabfoo).
You need to indicate :
-- position of the first element (Rhs) on stack
-- pointer on scilab function
-- number of Lhs (output of scilab function called)
-- number of Rhs (input of scilab function called)
call_scifunction.sce:
// =============================================================================
// Allan CORNET - DIGITEO - 2009
// This file is released into the public domain
// =============================================================================
files=['sci_call_scifunc.c'];
ilib_build('callscifunc',['call_scifunc','sci_call_scifunc'],files,[]);
// =============================================================================
exec loader.sce;
// =============================================================================
function r = scilabfoo(x,y)
r = x + y;
endfunction
// =============================================================================
v = call_scifunc(30,12,scilabfoo);
disp('result : ' + string(v));
v = call_scifunc(300,120,scilabfoo);
disp('result : ' + string(v));
// =============================================================================
ulink();
// =============================================================================sci_call_scifunc.sce:
//-------------------------------------------------------------------------------------
/*
* Scilab ( http://www.scilab.org/ )
* Copyright (C) DIGITEO - Allan CORNET - 2009
*
* This file is released into the public domain
*/
#include "stack-c.h"
#include "Scierror.h"
#include "localization.h"
//-------------------------------------------------------------------------------------
static int PutOneValueOnStack(double v);
//-------------------------------------------------------------------------------------
int sci_call_scifunc(char *fname)
{
int m1 = 0, n1 = 0, l1 = 0;
double v1 = 0.;
int m2 = 0, n2 = 0, l2 = 0;
double v2 = 0.;
int m3 = 0, n3 = 0, l3 = 0;
int rm1 = 0, rn1 = 0, rl1 = 0;
double r = 0.;
int positionFirstElementOnStackForScilabFunction = 0;
int numberOfRhsOnScilabFunction = 0;
int numberOfLhsOnScilabFunction = 0;
int pointerOnScilabFunction = 0;
CheckRhs(3,3);
CheckLhs(1,1);
if (GetType(1) != sci_matrix) /* Note that this code is deprecated and should be replaced by API_Scilab */
{
Scierror(999,_("%s: Wrong type for input argument #%d: A real expected.\n"),fname,1);
return 0;
}
GetRhsVar(1, MATRIX_OF_DOUBLE_DATATYPE, &m1, &n1, &l1); /* Note that this code is deprecated and should be replaced by API_Scilab */
if ( (m1 == n1) && (n1 == 1) )
{
v1 = *stk(l1);
}
else
{
Scierror(999,_("%s: Wrong size for input argument #%d: A scalar expected.\n"),fname,1);
return 0;
}
if (GetType(2) != sci_matrix) /* Note that this code is deprecated and should be replaced by API_Scilab */
{
Scierror(999,_("%s: Wrong type for input argument #%d: A real expected.\n"),fname,2);
return 0;
}
GetRhsVar(2, MATRIX_OF_DOUBLE_DATATYPE, &m2, &n2, &l2); /* Note that this code is deprecated and should be replaced by API_Scilab */
if ( (m2 == n2) && (n2 == 1) )
{
v2 = *stk(l2);
}
else
{
Scierror(999,_("%s: Wrong size for input argument #%d: A scalar expected.\n"),fname,2);
return 0;
}
if (GetType(3) != sci_c_function)
{
Scierror(999,_("%s: Wrong type for input argument #%d: A scilab function expected.\n"),fname,3);
return 0;
}
// get pointer on external function (here scilabfoo)
GetRhsVar(3, EXTERNAL_DATATYPE, &m3, &n3, &l3); /* Note that this code is deprecated and should be replaced by API_Scilab */
// r = scilabfoo(x, y)
// rhs eq. 2
// lhs eq. 1
// Position first element on Stack to use by Scilab Function
// v = call_scifunc(300,120,scilabfoo);
// On stack : 300 is on Top position (1)
// 120 second position
// scilabfoo third position
// we want to pass 300 & 120 to scilab Function
// First position is here : 1
positionFirstElementOnStackForScilabFunction = 1;
numberOfRhsOnScilabFunction = 2;
numberOfLhsOnScilabFunction = 1;
pointerOnScilabFunction = l3;
// r = scilabfoo(x, y)
// C2F(scifunction) call a scilab function
C2F(scifunction)(&positionFirstElementOnStackForScilabFunction,
&pointerOnScilabFunction,
&numberOfLhsOnScilabFunction,
&numberOfRhsOnScilabFunction);
// result r is now on first position on stack
GetRhsVar(1, MATRIX_OF_DOUBLE_DATATYPE, &rm1, &rn1, &rl1); /* Note that this code is deprecated and should be replaced by API_Scilab */
r = *stk(rl1);
PutOneValueOnStack(r);
return 0;
}
//-------------------------------------------------------------------------------------
static int PutOneValueOnStack(double v)
{
int m = 1,n = 1, l = 0;
CreateVar( Rhs+1, MATRIX_OF_DOUBLE_DATATYPE, &m, &n, &l ); /* Note that this code is deprecated and should be replaced by API_Scilab */
*stk(l) = v;
LhsVar(1) = Rhs + 1;
return 0;
}
//-------------------------------------------------------------------------------------result : 42 result : 420
a example with input arguments for "scilabfoo" are created from C code.
// =============================================================================
// Allan CORNET - DIGITEO - 2009
// This file is released into the public domain
// =============================================================================
files=['sci_call_scifunc2.c'];
ilib_build('callscifunc2',['call_scifunc2','sci_call_scifunc2'],files,[]);
// =============================================================================
exec loader.sce;
// =============================================================================
function r = scilabfoo(x,y)
disp("x =");
disp(x);
disp("y =");
disp(y);
r = x + y;
endfunction
// =============================================================================
v = call_scifunc2(scilabfoo);
disp('result : ' + string(v));
// =============================================================================
//ulink();
// =============================================================================//-------------------------------------------------------------------------------------
/*
* Scilab ( http://www.scilab.org/ )
* Copyright (C) DIGITEO - Allan CORNET - 2009
*
* This file is released into the public domain
*/
#include "stack-c.h"
#include "Scierror.h"
#include "localization.h"
//-------------------------------------------------------------------------------------
static int PutOneValueOnStack(double v);
//-------------------------------------------------------------------------------------
int sci_call_scifunc2(char *fname)
{
int m1 = 0, n1 = 0, l1 = 0;
double v1 = 0.;
int one = 1, l = 0;
int rm1 = 0, rn1 = 0, rl1 = 0;
double r = 0.;
int positionFirstElementOnStackForScilabFunction = 0;
int numberOfRhsOnScilabFunction = 0;
int numberOfLhsOnScilabFunction = 0;
int pointerOnScilabFunction = 0;
CheckRhs(1,1);
CheckLhs(1,1);
if (GetType(1) != sci_c_function) /* Note that this code is deprecated and should be replaced by API_Scilab */
{
Scierror(999,_("%s: Wrong type for input argument #%d: A scilab function expected.\n"),fname,1);
return 0;
}
// get pointer on external function (here scilabfoo)
GetRhsVar(1, EXTERNAL_DATATYPE, &m1, &n1, &l1);
// r = scilabfoo(x, y)
// rhs eq. 2
// lhs eq. 1
// creates a variable (double) on stack @ Rhs + 1
CreateVar(Rhs + 1 , MATRIX_OF_DOUBLE_DATATYPE, &one, &one,&l);
*stk(l) = 3.0;
// creates a variable (double) on stack @ Rhs + 2
CreateVar(Rhs + 2 , MATRIX_OF_DOUBLE_DATATYPE, &one, &one,&l);
*stk(l) = 2.0;
positionFirstElementOnStackForScilabFunction = Rhs + 1 ;
numberOfRhsOnScilabFunction = 2;
numberOfLhsOnScilabFunction = 1;
pointerOnScilabFunction = l1;
// r = scilabfoo(x, y)
SciFunction(&positionFirstElementOnStackForScilabFunction,
&pointerOnScilabFunction,
&numberOfLhsOnScilabFunction,
&numberOfRhsOnScilabFunction);
// result r is now on first position on stack
GetRhsVar(positionFirstElementOnStackForScilabFunction, MATRIX_OF_DOUBLE_DATATYPE, &rm1, &rn1, &rl1);
r = *stk(rl1);
PutOneValueOnStack(r);
return 0;
}
//-------------------------------------------------------------------------------------
static int PutOneValueOnStack(double v)
{
int m = 1,n = 1, l = 0;
CreateVar( Rhs+1, MATRIX_OF_DOUBLE_DATATYPE, &m, &n, &l );
*stk(l) = v;
LhsVar(1) = Rhs + 1;
return 0;
}
//--------------------------------------------------------------------------------------->function r = scilabfoo(x,y)
--> disp("x =");
--> disp(x);
--> disp("y =");
--> disp(y);
--> r = x + y;
-->endfunction
-->// =============================================================================
-->v = call_scifunc2(scilabfoo);
x =
3.
y =
2.
-->disp('result : ' + string(v));
result : 5Another way to call a scilab function (macro) is to use C2F(scistring)
C2F(scistring)(&positionFirstElementOnStackForScilabFunction, name, &numberOfLhsOnScilabFunction,
&numberOfRhsOnScilabFunction,
(unsigned long) strlen(name) ); /* Note that this code is deprecated and should be replaced by API_Scilab */name is a string with name of function to call