Search code examples
functionpointersparameter-passingpass-by-referencescilab

How pass variables by reference to a Scilab function


I want to have a Scilab function which is able to alter its input variables, For example in C I could have

void double(int* x){
    *x *= 2;
    return;
}

There are intppty, funptr, addinter, istk, sadr and stk in Scilab which seem to be relevant, however I can't find any working example. Scilab does have a pointer type (i.e. 128). I would appreciate if you could help me figure this out.

P.S.1. I have also mirrored this question here on Reddit.

P.S.2. Scilab also have intersci, SWIG, fort, external, call, API_Scilab/gateway which can interface C/C++ functions or Fortran subroutines. Unfortunately intersci has been deprecated and SWIG seems to be only for Linux with limited C++ compatibility.

P.S.3. scilab has function overloading which can do stuff with the functions defined by deff and a combination of %,<...>,_... syntax.

P.S.4. The way API_Scilab/gateway works, is basically you dvelop the code using functionalities provided bu the header file api_scilab.h, compile it with ilib_build, write a loader*.sce script and then load it with exec.

P.S.5. supposedly one should be able to install mingw compiler with

atomsInstall('mingw'); atomsLoad('mingw');

However I am not able to get it to work as I have explained here.


Solution

  • This is possible by using, e.g. a C++ Scilab 6 gateway (example needs a compiler on the machine, it should not be a problem for Linux and OSX users):

    gw=[
    "#include ""double.hxx"""
    "#include ""function.hxx"""
    "types::Function::ReturnValue sci_incr(types::typed_list &in, int _iRetCount,"
    "                                      types::typed_list &out)"
    "{"    
    "    if (in.size() != 1 || in[0]->isDouble() == false) {"
    "        throw ast::InternalError(""Wrong type/number of input argument(s)"");"
    "    }"
    "    types::Double *pDbl = in[0]->getAs<types::Double>();"
    "    double *pdbl = pDbl->get();"
    ""    
    "    for (int i=0; i < pDbl->getSize(); i++) (*pdbl) += 1.0;"
    ""
    "    return types::Function::OK;"
    "}"];
    cd TMPDIR;
    mputl(gw,TMPDIR+"/sci_incr.cpp");
    ulink
    ilib_build("incr", ["incr" "sci_incr" "cppsci"],"sci_incr.cpp", [])
    exec loader.sce
    

    After compilation/link of the interface, you can have the following behavior:

    --> x=1
     x  = 
    
       1.
    
    --> incr(x)
    
    --> x
     x  = 
    
       2.
    

    However, don't consider this as a feature, because the Scilab language has not been designed to use it !