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 : 5
Another 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