« Previous « Start » Next »
7 Calling TOMLAB from C/C++
This section describes how to create a standalone shared library
with TOMLAB functionality using the MCC compiler.
The guide covers MCC 3 as well as MCC 4. If using MCC 3, make sure
to patch it to R13SP1.
7.1 Creating a stand alone shared library
The procedure to create a standalone shared library of TOMLAB files
is identical to creating a standalone application, except for the
commands to compile and link the files. As described earlier, copy
all needed m-files and mex-files to a single directory. If needed,
create new m-files as an interface between TOMLAB and C/C++. These
can be used as entry points to the shared library (although, all
m-files can be used as entry points).
A suitable entry point could be an m-file taking F, c, A, b_L,
b_U, x_L and x_U matrices as input, generating a QP Prob struct
out of this, and calling a suitable solver. Only the results of
interest, for example the optimal vector x and objective function
value, could be returned.
After all MATLAB files have been put in a single directory, compile
them into a shared library using the following command:
> mcc -B csharedlib:<lib-name> <m-files> <mex-files>
This creates a shared library:
<lib-name>
with extension depending
on platform (.dll on Windows, .so on Linux).
If the client to use the shared library is written in C++ one
can build a C++ shared library supporting exception handling and C++
classes for handling the MATLAB arrays. The command to compile a C++
shared library is:
> mcc -B cpplib:<library name> <m-files> <mex-files>
For more detailed information about this, refer to:
http://www.mathworks.com/access/helpdesk/help/toolbox/compiler/
7.2 Calling the shared library from C/C++
The new shared library now contains entry points for all files
compiled with MCC; mex-files as well as m-files. Each m-file has two
library functions that may call it:
mlxFunctionname
mlfFunctionname
Notice that the first character in the function name is always upper
case. The rest of the characters are always lower case, regardless of
the case of the original function.
The difference between the two functions prefixed with mlx and mlf
is the way the arguments are passed. The mlx-function expects the
arguments like this:
extern void mlxSolveqp(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);
just like a mex-file (Refer to the MATLAB documentation for more
details and information on this.)
The mlf-function is perhaps more user friendly, as it looks more
like the original function call in MATLAB. Observe that the
arguments to the mlf-functions differ between MCC 3 and MCC 4.
The MATLAB function:
function [x, f] = solveqp(F, c, A, b_L, b_U, x_L, x_U)
is declared in the standalone library as follows when using MCC 4:
extern void mlfSolveqp(int nargout, mxArray** x, mxArray** f, mxArray* F
, mxArray* c, mxArray* A, mxArray* b_L
, mxArray* b_U, mxArray* x_L, mxArray* x_U);
A MATLAB function without left hand side arguments do not have the
nargout and pointer to pointer arguments.
The same MATLAB function is declared like this when using MCC 3:
extern mxArray * mlfSolveqp(mxArray * * f,
mxArray * F,
mxArray * c,
mxArray * A,
mxArray * b_L,
mxArray * b_U,
mxArray * x_L,
mxArray * x_U);
The return value is the first left hand side parameter; the MATLAB x
in this case.
In order to call these function in the shared library from a client
application, there are some tasks that must be completed before
anything else. First of all, one has to include a header file in the
application generated by the MCC compiler when compiling the
library. The name of the file is the name of the library plus the
extension .h. Each time the shared library is recompiled a new
header file will be generated. This header file includes all
necessary function declarations needed when calling a shared
library, setting up input data and reading output data. No other
header files need to be included in order to use the shared library.
Before using any of the MATLAB API functions, a function
mclInitializeApplication() has to be called. This only applies to
MCC 4 though. In MCC 3 there is no
mclInitializeApplication()
-function.
Before calling any of the functions in the shared library, an
initialization function has to be called. The name of this function
is:
<lib-name>Initialize()
, where
<lib-name>
is the
name of the library (including the
lib
prefix on Linux).
When these two (or one in MCC 3) functions have been called, all m-
and mex-files are callable from within the application using the
prefixes
mlf
or
mlx
. At this point the application
could for example read measurement data from a device or read input
data from a user interface, then formulate an optimization problem
and call TOMLAB through the shared library. It is recommended to
write m-files for compilation with the shared library to act as an
interface between the application and TOMLAB as it is usually easier
to handle MATLAB data in the MATLAB language than in C.
When all calls to the shared library are done, a termination
function should be called:
<lib-name>Terminate()
where
<lib-name>
is the name of the library (including the
lib
prefix on Linux).
When the MATLAB API functions are not needed anymore, call
mclTerminateApplication()
. This only applies to MCC 4.
To compile the application, use the mbuild utility:
On Windows:
> mbuild <source code files> <lib-name>.lib
where
<source code files>
are the source code files for the
application, and
<lib-name>
is the name of the shared library
generated by MCC earlier.
On Linux:
> mbuild <source code files> -l<lib-name> -L. -I.
where
<source code files>
are the source code files for the
application, and
<lib-name>
is the shared library generated
by MCC earlier
without the
lib
-prefix and
without the extension.
7.3 TOMLAB /CPLEX QP solver example
The TOMLAB distribution includes an example running TOMLAB /CPLEX for
a QP problem from a separate C application. It is available in the
TOMLAB distribution in the
/examples/sal/sallib
directory.
In summary, the example was constructed like this:
-
An m-file called solveqp.m was created to take simple input
in the form of matrices for F, c, A, b_L, b_U, x_L and x_U. This
m-file creates a QP Prob structure from these matrices and runs the
TOMLAB /CPLEX solver through tomRun and returns the optimal vector x and
objective function value.
- The profiler in MATLAB was turned on and the solveqp function was
called with some QP data. When a solution was obtained, the profile
report command displayed the m- and mex-files used during the
execution.
- The files were copied to a project directory for the new shared
library.
- In xnargin.m, some changes were made in order to have more
descriptive error messages when failing to find a specific
function. See xnargin.m for instructions on what to change.
- The library was built using the MCC compiler. (See the make file
for the example for details).
- A simple client application was written creating input data for the
solveqp.m function, calling it and writing the results to
the screen. (See the Appendix A for example
code).
- The application was built using the mbuild command. (See the make
file of the example for details).
- The application was run, and there were some error messages
reporting missing files.
- The missing files were added to the command building the library,
and the library was rebuilt.
- Step 8 and 9 were repeated a few of times until everything
was working smoothly.
Source files for the simple client application (
application.c)
and the interface m-file (
solveqp.m) are available in Appendix
A of this document.
« Previous « Start » Next »