1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
\subsection{externalproc}
\label{labexternalproc}
\noindent Name: \textbf{externalproc}\\
\phantom{aaa}binds an external code to a \sollya procedure\\[0.2cm]
\noindent Library names:\\
\verb| sollya_obj_t sollya_lib_externalprocedure(sollya_externalprocedure_type_t, |\\
\verb| sollya_externalprocedure_type_t *,|\\
\verb| int, char *, void *);|\\
\verb| sollya_obj_t sollya_lib_externalprocedure_with_data(|\\
\verb| sollya_externalprocedure_type_t, |\\
\verb| sollya_externalprocedure_type_t *,|\\
\verb| int, char *, void *, void *,|\\
\verb| void (*)(void *));|\\[0.2cm]
\noindent Usage:
\begin{center}
\textbf{externalproc}(\emph{identifier}, \emph{filename}, \emph{argumenttype} \texttt{->} \emph{resulttype}) : (\textsf{identifier type}, \textsf{string}, \textsf{type type}, \textsf{type type}) $\rightarrow$ \textsf{void}\\
\end{center}
Parameters:
\begin{itemize}
\item \emph{identifier} represents the identifier the code is to be bound to
\item \emph{filename} of type \textsf{string} represents the name of the object file where the code of procedure can be found
\item \emph{argumenttype} represents a definition of the types of the arguments of the \sollya procedure and the external code
\item \emph{resulttype} represents a definition of the result type of the external code
\end{itemize}
\noindent Description: \begin{itemize}
\item \textbf{externalproc} allows for binding the \sollya identifier \emph{identifier} to an
external code. After this binding, when \sollya encounters \emph{identifier}
applied to a list of actual parameters, it will evaluate these parameters and
call the external code with these parameters. If the external code indicated
success, it will receive the result produced by the external code, transform
it to \sollya's internal representation and return it.
In order to allow correct evaluation and typing of the data in parameter and
in result to be passed to and received from the external code, \textbf{externalproc}
has a third parameter \emph{argumenttype} \texttt{->} \emph{resulttype}. Both \emph{argumenttype} and
\emph{resulttype} are one of \textbf{void}, \textbf{constant}, \textbf{function}, \textbf{object}, \textbf{range}, \textbf{integer},
\textbf{string}, \textbf{boolean}, \textbf{list of} \textbf{constant}, \textbf{list of} \textbf{function}, \textbf{list of} \textbf{object},
\textbf{list of} \textbf{range}, \textbf{list of} \textbf{integer}, \textbf{list of} \textbf{string}, \textbf{list of} \textbf{boolean}.
It is worth mentioning that the difference between the data and
result type \textbf{function} and the type \textbf{object} is minimal and due to
support of legacy \sollya code. Both \sollya functions and \sollya
objects are transferred from and to the external procedure thru the C
type \texttt{sollya\_obj\_t}. The difference is that
\sollya will check that a certain object is a mathematical function
when \textbf{function} is used as a type, and will skip this test if the
\textbf{object} type is used. Similarly, \sollya relies on an object produced
by the external procedure to be a mathematical function when \textbf{function}
is used and will not make this assumption for \textbf{object}.
If upon a usage of a procedure bound to an external procedure the type of the
actual parameters given or its number is not correct, \sollya produces a type
error. An external function not applied to arguments represents itself and
prints out with its argument and result types.
The external function is supposed to return an integer indicating success. It
returns its result depending on its \sollya result type as follows. Here, the
external procedure is assumed to be implemented as a C function.\begin{itemize}
\item If the \sollya result type is void, the C function has no pointer
argument for the result.
\item If the \sollya result type is \textbf{constant}, the first argument of the
C function is of C type \texttt{mpfr\_t *}, the result is returned by affecting
the MPFR variable.
\item If the \sollya result type is \textbf{function}, the first argument of the
C function is of C type \texttt{sollya\_obj\_t *}, the result is returned by
affecting the \texttt{sollya\_obj\_t} variable.
\item If the \sollya result type is \textbf{object}, the first argument of the
C function is of C type \texttt{sollya\_obj\_t *}, the result is returned by
affecting the \texttt{sollya\_obj\_t} variable.
\item If the \sollya result type is \textbf{range}, the first argument of the C function
is of C type \texttt{mpfi\_t *}, the result is returned by affecting the MPFI
variable.
\item If the \sollya result type is \textbf{integer}, the first argument of the
C function is of C type \texttt{int *}, the result is returned by affecting the
int variable.
\item If the \sollya result type is \textbf{string}, the first argument of the
C function is of C type \texttt{char **}, the result is returned by the \texttt{char *}
pointed with a new \texttt{char *}.
\item If the \sollya result type is \textbf{boolean}, the first argument of the
C function is of C type \texttt{int *}, the result is returned by affecting the
int variable with a boolean value.
\item If the \sollya result type is \textbf{list of} type, the first argument of the
C function is of a C type depending on the \sollya return type:\begin{itemize}
\item For a list of \textbf{constant}: \verb|sollya_constant_list_t *|
\item For a list of \textbf{function}: \verb|sollya_obj_list_t *|
\item For a list of \textbf{object}: \verb|sollya_obj_list_t *|
\item For a list of \textbf{range}: \verb|sollya_constant_list_t *|
\item For a list of \textbf{integer}: \verb|sollya_int_list_t *|
\item For a list of \textbf{string}: \verb|sollya_string_list_t *|
\item For a list of \textbf{boolean}: \verb|sollya_boolean_list_t *| \end{itemize}
\end{itemize}
The external procedure affects its possible pointer argument if and only if
it succeeds. This means, if the function returns an integer indicating
failure, it does not leak any memory to the encompassing environment.
The external procedure receives its arguments as follows: If the \sollya
argument type is \textbf{void}, no argument array is given. Otherwise the C function
receives a C \texttt{void **} argument representing an array of size equal to the
arity of the function where each entry (of C type \texttt{void *}) represents a value
with a C type depending on the corresponding \sollya type.\begin{itemize}
\item If the \sollya type is \textbf{constant}, the \texttt{void *} is to be cast to \texttt{mpfr\_t *}.
\item If the \sollya type is \textbf{function}, the \texttt{void *} is to be cast to
\texttt{sollya\_obj\_t}.
\item If the \sollya type is \textbf{object}, the \texttt{void *} is to be cast to \texttt{sollya\_obj\_t}.
\item If the \sollya type is \textbf{range}, the \texttt{void *} is to be cast to \texttt{mpfi\_t *}.
\item If the \sollya type is \textbf{integer}, the \texttt{void *} is to be cast to \texttt{int *}.
\item If the \sollya type is \textbf{string}, the \texttt{void *} is to be cast to \texttt{char *}.
\item If the \sollya type is \textbf{boolean}, the \texttt{void *} is to be cast to \texttt{int *}.
\item If the \sollya type is \textbf{list of} type, the \texttt{void *} is to be cast to a list
of a type depending on the type of the list argument:\begin{itemize}
\item For a list of \textbf{constant}: \verb|sollya_constant_list_t|
\item For a list of \textbf{function}: \verb|sollya_obj_list_t|
\item For a list of \textbf{object}: \verb|sollya_obj_list_t|
\item For a list of \textbf{range}: \verb|sollya_interval_list_t|
\item For a list of \textbf{integer}: \verb|sollya_int_list_t|
\item For a list of \textbf{string}: \verb|sollya_string_list_t|
\item For a list of \textbf{boolean}: \verb|sollya_boolean_list_t| \end{itemize}
\end{itemize}
The external procedure is not supposed to alter the memory pointed by its
array argument \texttt{void **}.
In both directions (argument and result values), empty lists are represented
by \texttt{NULL} pointers.
Similarly to internal procedures, externally bounded procedures can be
considered to be objects inside \sollya that can be assigned to other
variables, stored in list etc.
\item The user should be aware that they may use the \sollya library in external
codes to be dynamically bound to \sollya using \textbf{externalproc}. On most systems,
it suffices to include the header of the \sollya library into the source code
of the external procedure. Linking with the actual \sollya library is not
necessary on most systems; as the interactive \sollya executable contains a
superset of the \sollya library functions. On some systems, linking with the
\sollya library or some of its dependencies may be necessary.
In particular, the \sollya library --~and, of course, its header file~--
contain a certain set of functions to manipulate lists with elements of
certain types, such as \verb|sollya_constant_list_t|, \verb|sollya_obj_list_t| and so on.
As explained above, these types are passed in argument to (and received back
thru a reference from) an external procedure. These list manipulation
functions are not strictly necessary to the use of the \sollya library in
free-standing applications that do not use the functionality provided with
\textbf{externalproc}. They are therefore provided as-is without any further
documentation, besides the comments given in the \sollya library header file.
\item The dynamic object file whose name is given to \textbf{externalproc} for binding of
an external procedure may also define a destructor function
\verb|int sollya_external_lib_close(void)|. If \sollya finds such a destructor
function in the dynamic object file, it will call that function when closing
the dynamic object file again. This happens when \sollya is terminated or when
the current \sollya session is restarted using \textbf{restart}. The purpose of the
destructor function is to allow the dynamically bound code to free any memory
that it might have allocated before \sollya is terminated or restarted.
The dynamic object file is not necessarily needed to define a destructor
function. This ensure backward compatibility with older \sollya external
library function object files.
When defined, the destructor function is supposed to return an integer
value indicating if an error has happened. Upon success, the destructor
functions is to return a zero value, upon error a non-zero value.
\end{itemize}
\noindent Example 1:
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> bashexecute("gcc -fPIC -Wall -c externalprocexample.c");
> bashexecute("gcc -fPIC -shared -o externalprocexample externalprocexample.o");
> externalproc(foo, "./externalprocexample", (integer, integer) -> integer);
> foo;
foo
> foo(5, 6);
11
> verbosity = 1!;
> foo();
Warning: at least one of the given expressions or a subexpression is not correct
ly typed
or its evaluation has failed because of some error on a side-effect.
error
> a = foo;
> a(5,6);
11
\end{Verbatim}
\end{minipage}\end{center}
See also: \textbf{library} (\ref{lablibrary}), \textbf{libraryconstant} (\ref{lablibraryconstant}), \textbf{externaldata} (\ref{labexternaldata}), \textbf{externalplot} (\ref{labexternalplot}), \textbf{bashexecute} (\ref{labbashexecute}), \textbf{void} (\ref{labvoid}), \textbf{constant} (\ref{labconstant}), \textbf{function} (\ref{labfunction}), \textbf{range} (\ref{labrange}), \textbf{integer} (\ref{labinteger}), \textbf{string} (\ref{labstring}), \textbf{boolean} (\ref{labboolean}), \textbf{list of} (\ref{lablistof}), \textbf{object} (\ref{labobject})
|