<?xml version="1.0" encoding="UTF-8"?>
<!--
 * Scilab ( https://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) INRIA -
 * Copyright (C) DIGITEO - 2012 - Allan CORNET
 *
 * Copyright (C) 2012 - 2016 - Scilab Enterprises
 *
 * This file is hereby licensed under the terms of the GNU GPL v2.0,
 * pursuant to article 5.3.4 of the CeCILL v.2.1.
 * This file was originally licensed under the terms of the CeCILL v2.1,
 * and continues to be available under such terms.
 * For more information, see the COPYING file which you should have received
 * along with this program.
 *
 -->
<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
          xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns3="http://www.w3.org/1999/xhtml"
          xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook"
          xmlns:scilab="http://www.scilab.org" xml:id="call" xml:lang="en">
    <refnamediv>
        <refname>call</refname>
        <refpurpose>Fortran or C user routines call</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <title>Syntax</title>
        <synopsis>// long form 'out' is present
            [y1,...,yk] = call("ident", x1,px1,"tx1", ...,xn,pxn,"txn", "out", [ny1,my1],py1,"ty1", ...,[nyl,myl],pyl,"tyl")
            // short form : no 'out' parameter
            [y1,....,yk] = call("ident", x1, ..., xn)
        </synopsis>
    </refsynopsisdiv>
    <refsection>
        <title>Arguments</title>
        <variablelist>
            <varlistentry>
                <term>"ident"</term>
                <listitem>
                    <para>string.</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>xi</term>
                <listitem>
                    <para>real matrix or string</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>pxi, pyi</term>
                <listitem>
                    <para>integers</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>txi, tyi</term>
                <listitem>
                    <para>
                        character string <literal>"d"</literal>,
                        <literal>"r"</literal>, <literal>"i"</literal> or
                        <literal>"c"</literal>.
                    </para>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection>
        <title>Description</title>
        <para>Interactive call of Fortran (or C) user program from Scilab. The
            routine must be previously linked with Scilab. This link may be
            done:
        </para>
        <itemizedlist>
            <listitem>
                <para>
                    with Scilab "<literal>link</literal>" command (dynamical
                    linking) during the Scilab session.(see
                    <literal>link</literal>)
                </para>
                <para>On Windows, C functions must use cdecl calling convention name
                    (see options in your C compiler(default calling convention for x86 C
                    compilers)).
                </para>
            </listitem>
        </itemizedlist>
        <para>There are two forms of calling syntax, a short one and a long one.
            The short one will give faster code and an easier calling syntax but one
            has to write a small (C or Fortran) interface in order to make the short
            form possible. The long one make it possible to call a Fortran routine (or
            a C one) without modification of the code but the syntax is more complex
            and the interpreted code slower.
        </para>
        <para>The meaning of each parameter is described now:</para>
        <variablelist>
            <varlistentry>
                <term>"ident"</term>
                <listitem>
                    <para>is the name of the called subroutine.</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>x1,...,xn</term>
                <listitem>
                    <para>are input variables (real matrices or strings) sent to the
                        routine,
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>px1,...,pxn</term>
                <listitem>
                    <para>are the respective positions of these variables in the calling
                        sequence of the routine <literal>"ident"</literal> and
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>tx1,...,txn</term>
                <listitem>
                    <para>
                        are their types (<literal>"r"</literal>,
                        <literal>"i"</literal>, <literal>"d"</literal> and
                        <literal>"c"</literal> for real (float) , integer, double precision
                        and strings)
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>"out"</term>
                <listitem>
                    <para>is a keyword used to separate input variables from output
                        variables. when this key word is present it is assumed that the long
                        form will be used and when it is not present, the short form is
                        used.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>[ny1, my1]</term>
                <listitem>
                    <para>
                        are the size (<literal>#</literal> of rows and columns. For
                        'c' arguments,<literal>m1*n1</literal> is the number of characters )
                        of output variables and
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>py1, ...</term>
                <listitem>
                    <para>are the positions of output variables (possibly equal to
                        <literal>pxi</literal> ) in the syntax of the routine. The
                        <literal>pyi</literal>'s integers must be in increasing
                        order.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>"ty1", ...</term>
                <listitem>
                    <para>are the Fortran types of output variables. The
                        <literal>k</literal> first output variables are put in
                        <literal>y1,..., yk</literal>.
                    </para>
                </listitem>
            </varlistentry>
        </variablelist>
        <para>If an output variable coincides with an input variable (i.e.
            <literal>pyi=pxj</literal> ) one can pass only its position
            <literal>pyi</literal> . The size and type of <literal>yi</literal> are
            then the same as those of <literal>xi</literal>. If an output variable
            coincides with an input variable and one specify the dimensions of the
            output variable <literal>[myl,nyl]</literal> must follow the compatibility
            condition <literal>mxk*nxk &gt;= myl*nyl</literal>.
        </para>
    </refsection>
    <refsection>
        <title>Examples</title>
            <para>Example #1 with a simple code in C language:
            </para>
            <programlisting role="example"><![CDATA[
if haveacompiler() then
    oldDir = pwd();
    Dir = fullfile(TMPDIR, "call");
    mkdir(Dir); cd(Dir)
    f1 = [
    '#include <math.h>'
    'void fooc(double c[],double a[],double *b,int *m,int *n)'
    '{'
    '   int i;'
    '   for ( i =0 ; i < (*m)*(*n) ; i++) '
    '     c[i] = sin(a[i]) + *b; '
    '}'];

    mputl(f1, "fooc.c");

    // Creating the shared library: Generates a gateway, a Makefile and a loader
    ilib_for_link('fooc', "fooc.c", [], "c")

    // load the shared library
    exec loader.sce

    // use the new primitive
    a = [1,2,3;4,5,6];
    b =  %pi;
    [m,n] = size(a);

    // Inputs:
    // a is in position 2 and double
    // b                3     double
    // n                4     integer
    // m                5     integer
    // Outputs:
    // c is in position 1 and double with size [m,n]
    c = call("fooc",a,2,"d",b,3,"d",m,4,"i",n,5,"i","out",[m,n],1,"d")

    cd(oldDir);
    dir(Dir)
end
         ]]></programlisting>
            <para/>
            <para>Example 2 with a simple code in Fortran:
            </para>
            <programlisting role="example"><![CDATA[
if haveacompiler() then
    oldDir = pwd();
    Dir = fullfile(TMPDIR, "call");
    mkdir(Dir); cd(Dir)
    f1 = ['      subroutine foof(c,a,b,n,m)'
    '      integer n,m'
    '      double precision a(*),b,c(*)'
    '      do 10 i=1,m*n '
    '        c(i) = sin(a(i))+b'
    '   10 continue'
    '      end'];
    mputl(f1,'foof.f')

    //creating the shared library (a gateway, a Makefile and a loader are
    //generated.

    ilib_for_link('foof','foof.f',[],"f")

    // load the shared library
    exec loader.sce

    // use the new primitive
    a = [1,2,3;4,5,6];
    b =  %pi;
    [m,n] = size(a);
    c = call("foof",a,2,"d",b,3,"d",m,4,"i",n,5,"i","out",[m,n],1,"d")
    cd(oldDir);
    dir(Dir)
end
        ]]></programlisting>
        <refsection>
            <title>Limitations to Shared Library Support</title>
            <para>Scilab shared library interface (call function) supports only C and fortran
                libraries routines.
            </para>
            <para>
                In others cases, we recommend to use <link linkend="api_scilab">api_scilab</link> interfaces.
            </para>
            <title>Troubleshooting Shared Library Applications (Windows)</title>
            <para>Some shared libraries, compiled as Microsoft Windows 32 or 64 bit
                libraries, use a calling convention that is incompatible with the
                default Scilab calling convention.
            </para>
            <para>The default calling convention for Scilab and for Microsoft C and
                C++ compilers is cdecl.
            </para>
            <para>
                For more information, see the  <ulink url="http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx">MSDN®
                    Calling Conventions
                </ulink>
                and  <ulink url="http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl">
                    Wikipedia
                </ulink>
                articles.
            </para>
        </refsection>
    </refsection>
    <refsection role="see also">
        <title>See also</title>
        <simplelist type="inline">
            <member>
                <link linkend="link">link</link>
            </member>
            <member>
                <link linkend="c_link">c_link</link>
            </member>
            <member>
                <link linkend="addinter">addinter</link>
            </member>
        </simplelist>
    </refsection>
</refentry>
