<?xml version="1.0" encoding="UTF-8"?>
<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="CallingAScilabFunctionFromACInterface" xml:lang="en">
    <refnamediv>
        <refname>Calling a scilab function (macros) from a C gateway</refname>
        <refpurpose>Calling a scilab function (macros) from a C interface</refpurpose>
    </refnamediv>
    <refsection>
        <title>Calling a scilab function (macros) from a C interface</title>
        <para>
            <warning>
                WARNING: This API is deprecated from Scilab 5.2.0 and is going to be removed with Scilab 6.0. Please use <link linkend="api_scilab">API Scilab</link> (the new Scilab API).
            </warning>
        </para>
        <para>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.
        </para>
        <para>The source files of this example are stored in the directory
            examples/call_scifunction.
        </para>
        <para>How to use this example:</para>
        <programlisting role=""><![CDATA[
exec call_scifunction.sce; // launch scilab
v = call_scifunc(30,12,scilabfoo);
 ]]></programlisting>
        <para>you pass a pointer on a scilab function (scilabfoo macro) to your
            function 'call_scifunc'.
        </para>
        <para>C2F(scifunction) calls another scilab function (here
            scilabfoo).
        </para>
        <para>You need to indicate :</para>
        <itemizedlist>
            <listitem>
                <para>position of the first element (Rhs) in the Scilab memory</para>
            </listitem>
            <listitem>
                <para>pointer on scilab function</para>
            </listitem>
            <listitem>
                <para>number of Lhs (output of scilab function called)</para>
            </listitem>
            <listitem>
                <para>number of Rhs (input of scilab function called)</para>
            </listitem>
        </itemizedlist>
        <para>The script call_scifunction.sce used to build and load the C
            interface into Scilab is the following:
        </para>
        <programlisting role=""><![CDATA[
files=['sci_call_scifunc.c']; // Defines the list of file
ilib_build('callscifunc',['call_scifunc','sci_call_scifunc'],files,[]); // Build the files and creates the loader

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(); // unload the dynamic library
 ]]></programlisting>
        <para>The file sci_call_scifunc.c is the following:</para>
        <programlisting role="code_gateway"><![CDATA[

#include "stack-c.h"
#include "Scierror.h"
#include "localization.h"

#error This code is deprecated

int sci_call_scifunc(char *fname)
{
  int m1    = 0, n1    = 0, l1    = 0;
  int m2    = 0, n2    = 0, l2    = 0;
  int m3    = 0, n3    = 0, l3    = 0;
  int rm1   = 0, rn1   = 0, rl1   = 0;
  int m_out = 1, n_out = 1, l_out = 0;
  double v1 = 0, v2 = 0, r = 0;
  int positionFirstElementOnStackForScilabFunction = 0;
  int numberOfRhsOnScilabFunction = 0;
  int numberOfLhsOnScilabFunction = 0;
  int pointerOnScilabFunction     = 0;

  CheckRhs(3,3);
  CheckLhs(0,1);

  if (GetType(1) != sci_matrix)
  {
    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);
  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)
  {
    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);
  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);

  // r = scilabfoo(x, y)
  // rhs eq. 2
  // lhs eq. 1

  // Position first element in the Scilab memory 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)
  // Scifunction call a scilab function
  Scifunction(&positionFirstElementOnStackForScilabFunction,
              &pointerOnScilabFunction,
              &numberOfLhsOnScilabFunction,
              &numberOfRhsOnScilabFunction);

  // result r is now on position positionFirstElementOnStackForScilabFunction on stack
  GetRhsVar(1, MATRIX_OF_DOUBLE_DATATYPE, &rm1, &rn1, &rl1);
  r = *stk(rl1);

  CreateVar(Rhs+1, MATRIX_OF_DOUBLE_DATATYPE, &m_out, &n_out, &l_out);
  *stk(l_out) = r;

  LhsVar(1) = Rhs + 1;

  return 0;
}
 ]]></programlisting>
        <para>The main function in this C file is Scifunction. It allows to call a
            Scilab function inside a C interface.
        </para>
    </refsection>
    <refsection role="see also">
        <title>See also</title>
        <simplelist type="inline">
            <member>
                <link linkend="Scierror">Scierror</link>
            </member>
            <!--<member><link linkend="Scifunction">Scifunction</link></member>-->
            <member>
                <link linkend="sci_types">sci_types</link>
            </member>
        </simplelist>
    </refsection>
</refentry>
