| MATLAB® Compiler™ | ![]() |
| On this page… |
|---|
The examples in this section illustrate how to mix M-files and C or C++ source code files:
The first example is a simple application that mixes M-files and C code.
The second example illustrates how to write C code that calls a compiled M-file.
One way to create a standalone application is to code some of it as one or more function M-files and to code other parts directly in C or C++. To write a standalone application this way, you must know how to do the following:
Call the external C or C++ functions generated by MATLAB Compiler.
Handle the results these C or C++ functions return.
Note If you include compiled M-code into a larger application, you must produce a library wrapper file even if you do not actually create a separate library. For more information on creating libraries, see Libraries. |
For more information on MX Array, see Using MX Array.
This example involves mixing M-files and C code. Consider a simple application whose source code consists of mrank.m, mrankp.c, main_for_lib.c, and main_for_lib.h.
mrank.m contains a function that returns a vector of the ranks of the magic squares from 1 to n.
function r = mrank(n) r = zeros(n,1); for k = 1:n r(k) = rank(magic(k)); end
Copy mrank.m, printmatrix.m, mrankp.c, main_for_lib.c, and main_for_lib.h into your current directory.
The steps needed to build this standalone application are:
To perform these steps, enter the following on a single line:
mcc -W lib:libPkg -T link:exe mrank printmatrix mrankp.c main_for_lib.c
The following flow diagram shows the mixing of M-files and C-files that forms this sample standalone application. The top part of the diagram shows the mcc process and the lower part shows the mbuild process.

MATLAB Compiler generates the following C source code files:
libPkg.c
libPkg.h
libPkg_mcc_component_data.c
This command invokes mbuild to compile the resulting MATLAB Compiler generated source files with the existing C source files (mrankp.c and main_for_lib.c) and link against the required libraries.
MATLAB Compiler provides two different versions of mrankp.c in the matlabroot/extern/examples/compiler directory:
mrankp.c contains a POSIX-compliant main function. mrankp.c sends its output to the standard output stream and gathers its input from the standard input stream.
mrankwin.c contains a Windows version of mrankp.c.
The code in mrankp.c calls mrank and outputs the values that mrank returns.
/*
* MRANKP.C
* "Posix" C main program
* Calls mlfMrank, obtained by using MCC to compile mrank.m.
*
* $Revision: 1.1.4.45 $
*
*/
#include <stdio.h>
#include <math.h>
#include "libPkg.h"
main( int argc, char **argv )
{
mxArray *N; /* Matrix containing n. */
mxArray *R = NULL; /* Result matrix. */
int n; /* Integer parameter from command line.*/
/* Get any command line parameter. */
if (argc >= 2) {
n = atoi(argv[1]);
} else {
n = 12;
}
mclInitializeApplication(NULL,0);
libPkgInitialize();/* Initialize library of M-Functions */
/* Create a 1-by-1 matrix containing n. */
N = mxCreateDoubleScalar(n);
/* Call mlfMrank, the compiled version of mrank.m. */
mlfMrank(1, &R, N);
/* Print the results. */
mlfPrintmatrix(R);
/* Free the matrices allocated during this computation. */
mxDestroyArray(N);
mxDestroyArray(R);
libPkgTerminate(); /* Terminate library of M-functions */
mclTerminateApplication();
}
The heart of mrankp.c is a call to the mlfMrank function. Most of what comes before this call is code that creates an input argument to mlfMrank. Most of what comes after this call is code that displays the vector that mlfMrank returns. First, the code must initialize the MCR and the generated libPkg library.
mclInitializeApplication(NULL,0); libPkgInitialize(); /* Initialize the library of M-Functions */
To understand how to call mlfMrank, examine its C function header, which is
void mlfMrank(int nargout, mxArray** r, mxArray* n);
According to the function header, mlfMrank expects one input parameter and returns one value. All input and output parameters are pointers to the mxArray data type. (See the External Interfaces documentation for details on the mxArray data type.)
To create and manipulate mxArray * variables in your C code, you can call the mx routines described in the External Interfaces documentation. For example, to create a 1-by-1 mxArray * variable named N with real data, mrankp calls mxCreateDoubleScalar.
N = mxCreateDoubleScalar(n);
mrankp can now call mlfMrank, passing the initialized N as the sole input argument.
R = mlfMrank(1,&R,N);
mlfMrank returns its output in a newly allocated mxArray * variable named R. The variable R is initialized to NULL. Output variables that have not been assigned to a valid mxArray should be set to NULL. The easiest way to display the contents of R is to call the mlfPrintmatrix function.
mlfPrintmatrix(R);
This function is defined in Printmatrix.m.
Finally, mrankp must free the heap memory allocated to hold matrices and call the termination functions.
mxDestroyArray(N); mxDestroyArray(R); libPkgTerminate(); /* Terminate the library of M-functions */ mclTerminateApplication(); /* Terminate the MCR */
This section provides an advanced example that illustrates how to write C code that calls a compiled M-file. Consider a standalone application whose source code consists of the files:
multarg.m, which contains a function named multarg
multargp.c, which contains C wrapper code that calls the C interface function for the M-code
printmatrix.m, which contains the helper function to print a matrix to the screen
main_for_lib.c, which contains one main function
main_for_lib.h, which is the header for structures used in main_for_lib.c and multargp.c
multarg.m specifies two input parameters and returns two output parameters.
function [a,b] = multarg(x,y) a = (x + y) * pi; b = svd(svd(a));
The code in multargp.c calls mlfMultarg and then displays the two values that mlfMultarg returns.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "libMultpkg.h"
/*
* Function prototype; MATLAB Compiler creates mlfMultarg
* from multarg.m
*/
void PrintHandler( const char *text )
{
printf(text);
}
int main( ) /* Programmer-written coded to call mlfMultarg */
{
#define ROWS 3
#define COLS 3
mclOutputHandlerFcn PrintHandler;
mxArray *a = NULL, *b = NULL, *x, *y;
double x_pr[ROWS * COLS] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
double x_pi[ROWS * COLS] = {9, 2, 3, 4, 5, 6, 7, 8, 1};
double y_pr[ROWS * COLS] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
double y_pi[ROWS * COLS] = {2, 9, 3, 4, 5, 6, 7, 1, 8};
double *a_pr, *a_pi, value_of_scalar_b;
/* Initialize with a print handler to tell mlfPrintMatrix
* how to display its output.
*/
mclInitializeApplication(NULL,0);
libMultpkgInitializeWithHandlers(PrintHandler,PrintHandler);
/* Create input matrix "x" */
x = mxCreateDoubleMatrix(ROWS, COLS, mxCOMPLEX);
memcpy(mxGetPr(x), x_pr, ROWS * COLS * sizeof(double));
memcpy(mxGetPi(x), x_pi, ROWS * COLS * sizeof(double));
/* Create input matrix "y" */
y = mxCreateDoubleMatrix(ROWS, COLS, mxCOMPLEX);
memcpy(mxGetPr(y), y_pr, ROWS * COLS * sizeof(double));
memcpy(mxGetPi(y), y_pi, ROWS * COLS * sizeof(double));
/* Call the mlfMultarg function. */
mlfMultarg(2, &a, &b, x, y);
/* Display the entire contents of output matrix "a". */
mlfPrintmatrix(a);
/* Display the entire contents of output scalar "b" */
mlfPrintmatrix(b);
/* Deallocate temporary matrices. */
mxDestroyArray(a);
mxDestroyArray(b);
libMultpkgTerminate();
mclTerminateApplication();
return(0);
}
You can build this program into a standalone application by entering this command on a single line:
mcc -W lib:libMultpkg -T link:exe multarg printmatrix multargp.c main_for_lib.c
The program first displays the contents of a 3-by-3 matrix a, and then displays the contents of scalar b.
6.2832 +34.5575i 25.1327 +25.1327i 43.9823 +43.9823i 12.5664 +34.5575i 31.4159 +31.4159i 50.2655 +28.2743i 18.8496 +18.8496i 37.6991 +37.6991i 56.5487 +28.2743i 143.4164
Invoking MATLAB Compiler on multarg.m generates the C function prototype.
extern void mlfMultarg(int nargout, mxArray** a, mxArray** b, mxArray* x, mxArray* y);
This C function header shows two input arguments (mxArray* x and mxArray* y) and two output arguments (the return value and mxArray** b).
Use mxCreateDoubleMatrix to create the two input matrices (x and y). Both x and y contain real and imaginary components. The memcpy function initializes the components, for example:
x = mxCreateDoubleMatrix(,ROWS, COLS, mxCOMPLEX); memcpy(mxGetPr(x), x_pr, ROWS * COLS * sizeof(double)); memcpy(mxGetPi(y), x_pi ROWS * COLS * sizeof(double));
The code in this example initializes variable x from two arrays (x_pr and x_pi) of predefined constants. A more realistic example would read the array values from a data file or a database.
After creating the input matrices, main calls mlfMultarg.
mlfMultarg(2, &a, &b, x, y);
The mlfMultarg function returns matrices a and b. a has both real and imaginary components; b is a scalar having only a real component. The program uses mlfPrintmatrix to output the matrices, for example:
mlfPrintmatrix(a);
![]() | Coding with M-Files Only | Libraries | ![]() |
| © 1984-2008- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |