[Contents] [TitleIndex] [WordIndex

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


2022-09-08 09:26