A shared library generated by MATLAB® Compiler SDK™ contains at least seven functions. There are three generated functions to manage library initialization and termination, one each for printed output and error messages, and two generated functions for each MATLAB file compiled into the library.
To generate the functions described in this section, first copy sierpinski.m
, main_for_lib.c
, main_for_lib.h
,
and triangle.c
from
into
your directory, and then execute the appropriate MATLAB Compiler SDK command.matlabroot
\extern\examples\compilersdk
mcc -W lib:libtriangle -T link:lib sierpinski.m mbuild triangle.c main_for_lib.c libtriangle.lib
mcc -W lib:libtriangle -T link:lib sierpinski.m mbuild triangle.c main_for_lib.c -L. -ltriangle -I.
mcc -W cpplib:libtrianglep -T link:lib sierpinski.m mbuild triangle.cpp main_for_lib.c libtrianglep.lib
mcc -W cpplib:libtriangle -T link:lib sierpinski.m mbuild triangle.cpp main_for_lib.c -L. -ltriangle -I.
These commands create a main program named triangle
,
and a shared library named libtriangle
. The library
exports a single function that uses a simple iterative algorithm (contained
in sierpinski.m
sierpinski.m
)
to generate the fractal known as Sierpinski's Triangle. The main program
in triangle.c
triangle.c
or triangle.cpp
triangle.cpp
can
optionally take a single numeric argument, which, if present, specifies
the number of points used to generate the fractal. For example, triangle
8000
generates a diagram with 8,000 points.
In this example, MATLAB Compiler SDK places all of the generated
functions into the generated file libtriangle.c
or libtriangle.cpp
.
All programs that call MATLAB Compiler SDK generated shared libraries have roughly the same structure:
Declare variables and process/validate input arguments.
Call mclInitializeApplication
,
and test for success. This function sets up the global MATLAB Runtime state
and enables the construction of MATLAB Runtime instances.
Call, once for each library, <libraryname>Initialize
,
to create the MATLAB Runtime instance required by the library.
Invoke functions in the library, and process the results. (This is the main body of the program.)
Call, once for each library, <libraryname>Terminate
,
to destroy the associated MATLAB Runtime.
Call mclTerminateApplication
to
free resources associated with the global MATLAB Runtime state.
Clean up variables, close files, etc., and exit.
To see these steps in an actual example, review the main program
in this example, triangle.c
triangle.c
.
The library initialization and termination functions create and destroy, respectively, the MATLAB Runtime instance required by the shared library. You must call the initialization function before you invoke any of the other functions in the shared library, and you should call the termination function after you are finished making calls into the shared library (or you risk leaking memory).
There are two forms of the initialization function and one type
of termination function. The simpler of the two initialization functions
takes no arguments; most likely this is the version your application
will call. In this example, this form of the initialization function
is called libtriangleInitialize
.
bool libtriangleInitialize(void)
This function creates an MATLAB Runtime instance using the default print and error handlers, and other information generated during the compilation process.
However, if you want more control over how printed output and error messages are handled, you may call the second form of the function, which takes two arguments.
bool libtriangleInitializeWithHandlers( mclOutputHandlerFcn error_handler, mclOutputHandlerFcn print_handler )
By calling this function, you can provide your own versions of the print and error handling routines called by the MATLAB Runtime. Each of these routines has the same signature (for complete details, see Print and Error Handling Functions). By overriding the defaults, you can control how output is displayed and, for example, whether or not it goes into a log file.
Note
Before calling either form of the library initialization routine,
you must first call |
On Microsoft® Windows® platforms, MATLAB Compiler SDK generates
an additional initialization function, the standard Microsoft DLL
initialization function DllMain
.
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void *pv)
The generated DllMain
performs a very important
service; it locates the directory in which the shared library is stored
on disk. This information is used to find the deployable archive,
without which the application will not run. If you modify the generated DllMain
(not
recommended), make sure you preserve this part of its functionality.
Library termination is simple.
void libtriangleTerminate(void)
Call this function (once for each library) before calling mclTerminateApplication
.
By default, MATLAB Compiler SDK generated applications and shared libraries send printed output to standard output and error messages to standard error. MATLAB Compiler SDK generates a default print handler and a default error handler that implement this policy. If you'd like to change this behavior, you must write your own error and print handlers and pass them in to the appropriate generated initialization function.
You may replace either, both, or neither of these two functions. The MATLAB Runtime sends all regular output through the print handler and all error output through the error handler. Therefore, if you redefine either of these functions, the MATLAB Runtime will use your version of the function for all the output that falls into class for which it invokes that handler.
The default print handler takes the following form.
static int mclDefaultPrintHandler(const char *s)
The implementation is straightforward; it takes a string, prints
it on standard output, and returns the number of characters printed.
If you override or replace this function, your version must also take
a string and return the number of characters "handled."
The MATLAB Runtime calls the print handler when an executing MATLAB file
makes a request for printed output, e.g., via the MATLAB function disp
.
The print handler does not terminate the output with a carriage return
or line feed.
The default error handler has the same form as the print handler.
static int mclDefaultErrorHandler(const char *s)
However, the default implementation of the print handler is slightly different. It sends the output to the standard error output stream, but if the string does not end with carriage return, the error handler adds one. If you replace the default error handler with one of your own, you should perform this check as well, or some of the error messages printed by the MATLAB Runtime will not be properly formatted.
Caution
The error handler, despite its name, does not handle the actual
errors, but rather the message produced after the errors have been
caught and handled inside the MATLAB Runtime. You cannot use this
function to modify the error handling behavior of the MATLAB Runtime --
use the |
Note:
If you provide alternate C++ implementations of either extern "C" int myPrintHandler(const char *s); |
For each MATLAB file specified on the MATLAB Compiler SDK command
line, the product generates two functions, the mlx
function
and the mlf
function. Each of these generated functions
performs the same action (calls your MATLAB file function). The
two functions have different names and present different interfaces.
The name of each function is based on the name of the first function
in the MATLAB file (sierpinski
, in this example);
each function begins with a different three-letter prefix.
Note:
For C shared libraries, MATLAB Compiler SDK generates the
|
The function that begins with the prefix mlx
takes
the same type and number of arguments as a MATLAB MEX-function.
(See the External Interfaces documentation for more details on MEX-functions.)
The first argument, nlhs
, is the number of output
arguments, and the second argument, plhs
, is a
pointer to an array that the function will fill with the requested
number of return values. (The "lhs
"
in these argument names is short for "left-hand side"
-- the output variables in a MATLAB expression are those on the
left-hand side of the assignment operator.) The third and fourth parameters
are the number of inputs and an array containing the input variables.
void mlxSierpinski(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
The second of the generated functions begins with the prefix mlf
.
This function expects its input and output arguments to be passed
in as individual variables rather than packed into arrays. If the
function is capable of producing one or more outputs, the first argument
is the number of outputs requested by the caller.
void mlfSierpinski(int nargout, mxArray** x, mxArray** y, mxArray* iterations, mxArray* draw)
In both cases, the generated functions allocate memory for their
return values. If you do not delete this memory (via mxDestroyArray
)
when you are done with the output variables, your program will leak
memory.
Your program may call whichever of these functions is more convenient,
as they both invoke your MATLAB file function in an identical
fashion. Most programs will likely call the mlf
form
of the function to avoid managing the extra arrays required by the mlx
form.
The example program in triangle.c
triangle.c
calls mlfSierpinski
.
mlfSierpinski(2, &x, &y, iterations, draw);
In this call, the caller requests two output arguments, x
and y
,
and provides two inputs, iterations
and draw
.
If the output variables you pass in to an mlf
function
are not NULL, the mlf
function will attempt to
free them using mxDestroyArray
. This means that
you can reuse output variables in consecutive calls to mlf
functions
without worrying about memory leaks. It also implies that you must
pass either NULL
or a valid MATLAB array for
all output variables or your program will fail because the memory
manager cannot distinguish between a non-initialized (invalid) array
pointer and a valid array. It will try to free a pointer that is not
NULL -- freeing an invalid pointer usually causes a segmentation fault
or similar fatal error.
If your MATLAB function interface uses varargin
or varargout
,
you must pass them as cell arrays. For example, if you have N
varargin
s,
you need to create one cell array of size 1-by-N
.
Similarly, varargout
s are returned back as one
cell array. The length of the varargout
is equal
to the number of return values specified in the function call minus
the number of actual variables passed. As in the MATLAB software,
the cell array representing varagout
has to be
the last return variable (the variable preceding the first input variable)
and the cell array representing varargin
s has to
be the last formal parameter to the function call.
For information on creating cell arrays, refer to the C MEX function interface in the External Interfaces documentation.
For example, consider this MATLAB file interface:
[a,b,varargout] = myfun(x,y,z,varargin)
The corresponding C interface for this is
void mlfMyfun(int numOfRetVars, mxArray **a, mxArray **b, mxArray **varargout, mxArray *x, mxArray *y, mxArray *z, mxArray *varargin)
In this example, the number of elements in varargout
is (numOfRetVars
- 2)
, where 2
represents the two variables, a
and b
,
being returned. Both varargin
and varargout
are
single row, multiple column cell arrays.
Caution
The C++ shared library interface does not support For example, compile some MATLAB code as a C++ shared library
using ... 'FOO' : function does not take 0 arguments mwArray junk; FOO(junk); FOO((mwArray)NULL); nargin=1 . In MATLAB, is nargin=0 and FOO([]) is nargin=1 .
|
C++ Interfaces for MATLAB Functions Using varargin and
varargout. The C++ mlx
interface for MATLAB functions
does not change even if the functions use varargin
or varargout
.
However, the C++ function interface (the second set of functions)
changes if the MATLAB function is using varargin
or varargout
.
For examples, view the generated code for various MATLAB function
signatures that use varargin
or varargout
.
Note: For simplicity, only the relevant part of the generated C++ function signature is shown in the following examples. |
function varargout = foo(varargin)
function varargout = foo(i1, i2, varargin)
When using shared libraries, you may call functions to retrieve specific information from the MATLAB Runtime state. For details, see Set and Retrieve MATLAB Runtime Data for Shared Libraries.