| MATLAB® | ![]() |
| On this page… |
|---|
You can call your own C, C++, or Fortran subroutines from the MATLAB® command line as if they were built-in functions. These programs are called binary MEX-files, which are dynamically linked subroutines that the MATLAB interpreter loads and executes. MEX stands for "MATLAB executable."
Note MATLAB supports MEX-files created in C++, with some limitations. For more information, see Creating C++ MEX-Files. |
MEX-files have several applications:
Large pre-existing C and Fortran programs can be called from MATLAB without having to be rewritten as M-files.
Performance-critical routines can be replaced with handcrafted C implementations.
MEX-files are not appropriate for all applications. MATLAB is a high-productivity environment whose specialty is eliminating time-consuming, low-level programming in compiled languages like Fortran or C. In general, you should do most of your programming in MATLAB. Do not use MEX-files unless your application requires it.
The term mex has different meanings, as shown in the following table:
| MEX Term | Definition |
|---|---|
| source MEX-file | C, C++, or Fortran source code file. |
| binary MEX-file | Dynamically linked subroutine executed in the MATLAB environment. |
| mex function library | MATLAB C and Fortran API library to perform operations in the MATLAB environment . |
| mex build script | MATLAB function to create a binary file from a source file. |
This section provides an overview of the elements of a source MEX-file and what you need to get started. To see a C language example, see Creating a Source MEX-File. For information about using specific MATLAB C and Fortran API library functions, see Workflow of a MEX-File.
Although you can create MEX-files in C, C++ or Fortran, for clarity, this topic is in the context of a C language program. For language-specific instructions for creating MEX-files, see Creating C Language MEX-Files and Creating Fortran MEX-Files.
Users who create source MEX-files should have the tools and knowledge to modify a C program. In particular, you need a compiler supported by MATLAB. For an up-to-date list of supported compilers, see Technical Note 1601: http://www.mathworks.com/support/tech-notes/1600/1601.html.
The source code that performs some function you want to use in conjunction with MATLAB software functionality is called a computational routine. If you created a stand alone C program for this code, it would have a main() function. MATLAB communicates with your MEX-file using a gateway routine. The MATLAB function that creates the gateway routine is mexfunction. You use mexfunction instead of main() in your source file.
MATLAB stores arrays in an mxArray type. Use mxArray in your C program to pass MATLAB data to and from your MEX-file.
The MATLAB C and Fortran API is the function reference for working with mxArray. This API has several libraries. Functions in the mx library create and manipulate MATLAB arrays. These functions are listed in the MX Array Manipulation category. Functions in the mex library perform operations in the MATLAB workspace. These functions are listed in the MEX-Files category.
To create a binary MEX-file, you need to:
Assemble your functions and the MATLAB API functions into one or more C source files.
Write a gateway function in one of your C source files.
Use the MATLAB mex function, called a build script, to build a binary MEX-file.
Use your binary MEX-file in MATLAB like any M-file or built-in function.
Before you start building binary MEX-files, you should select your default compiler and test an existing source MEX-file. For more information about compilers, and for step-by-step instructions for compiling sample programs, see Building Binary MEX-Files.
Suppose you have some C code, called arrayProduct, that multiplies an n-dimensional array y by a scalar value x and returns the results in array z. It may look something like the following:
void arrayProduct(double x, double *y, double *z, int n)
{
int i;
for (i=0; i<n; i++) {
z[i] = x * y[i];
}
}
If x = 5 and y is an array with values 1.5, 2, and 9, then calling:
arrayProduct(x,y,z,n)
creates an array z with the values 7.5, 10, and 45.
The following steps show you how to call this function in MATLAB using a MATLAB matrix, by creating the MEX-file arrayProduct.
Open the MATLAB Editor and copy your code into a new file. Save the file on your MATLAB path, for example, in c:\work, and name it arrayProduct.c. This is your computational routine and the name of your MEX-file.
At the beginning of the file, add the header file:
#include "mex.h"
Add comments:
/* * arrayProduct.c * Multiplies an input scalar times a 1xN matrix * and outputs a 1xN matrix * * This is a MEX-file for MATLAB. */
After the computational routine, add the gateway routine mexFunction:
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
/* variable declarations here */
/* code here */
}
The mx* and mex* functions use MATLAB preprocessor macros for cross-platform flexibility.
Edit your computational routine to use mwSize for mxArray size n and index i.
void arrayProduct(double x, double *y, double *z, mwSize n)
{
mwSize i;
for (i=0; i<n; i++) {
z[i] = x * y[i];
}
}
In this example, there are two input arguments (a matrix and a scalar) and one output argument (the product). To check that the number of input arguments nrhs is two and the number of output arguments nlhs is one, put the following code inside the mexFunction routine:
/* check for proper number of arguments */
if(nrhs!=2) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs",
"Two inputs required.");
}
if(nlhs!=1) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs",
"One output required.");
}
To validate the input values, enter:
/* make sure the first input argument is scalar */
if( !mxIsDouble(prhs[0]) ||
mxIsComplex(prhs[0]) ||
mxGetNumberOfElements(prhs[0])!=1 ) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notScalar",
"Input multiplier must be a scalar.");
}
The second input argument must be a row vector.
/* check that number of rows in second input argument is 1 */
if(mxGetM(prhs[1])!=1) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowVector",
"Input must be a row vector.");
}Put the following declaration statements at the beginning of your mexFunction:
double multiplier; /* input scalar */ double *inMatrix; /* 1xN input matrix */ mwSize ncols; /* size of matrix */
Add these statements to the code section of mexFunction:
/* get the value of the scalar input */ multiplier = mxGetScalar(prhs[0]); /* create a pointer to the real data in the input matrix */ inMatrix = mxGetPr(prhs[1]); /* get dimensions of the input matrix */ ncols = mxGetN(prhs[1]);
Put the following declaration statement after your input variable declarations:
double *outMatrix; /* output matrix */
Add these statements to the code section of mexFunction:
/* create the output matrix */ plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL); /* get a pointer to the real data in the output matrix */ outMatrix = mxGetPr(plhs[0]);
The following statement executes your function:
/* call the computational routine */ arrayProduct(multiplier,inMatrix,outMatrix,ncols);
Your source file should look something like arrayProduct.c, located in your matlabroot/extern/examples/mex directory. To see the contents of arrayProduct.c, open the file in the MATLAB Editor.
To build the binary MEX-file, at the MATLAB command prompt, type:
mex arrayProduct.c
Type:
s = 5; A = [1.5, 2, 9]; B = arrayProduct(s,A)
MATLAB displays:
B =
7.5000 10.0000 45.0000
To test error conditions, type:
arrayProduct
MATLAB displays:
??? Error using ==> arrayProduct Two inputs required.
This section discusses MATLAB API functions for handling the basic workflow of a MEX-file and uses C language code snippets for illustration. For an example of a complete C program, see Creating a Source MEX-File. Unless otherwise specified, in this section the term "MEX-file" refers to a source file.
Some basic programming tasks are:
Use the mexfunction function in your C source file as the interface between your code and MATLAB. Place this function after your computational routine and any other functions in your source.
The signature for mexfunction is:
void
mexFunction(int nlhs, mxArray *plhs[], ...
int nrhs, const mxArray *prhs[]);Use type mxArray to handle MATLAB arrays. The following statement declares an mxArray named myData:
mxArray *myData;
To define the values of myData, use one of the mxCreate* functions. Some useful array creation routines are mxCreateNumericArray, mxCreateCellArray, and mxCreateCharArray. For example, the following statement allocates an m-by-1 floating-point mxArray initialized to 0:
myData = mxCreateDoubleMatrix(m, 1, mxREAL);
C programmers should note that data in a MATLAB array is in column-major order. (For an illustration, see Data Storage.) Use the MATLAB mxGet* array access routines, described in Manipulating Data, to read data from an mxArray.
MATLAB passes data to and from MEX-files in a highly regulated way, described in Required Parameters.
Input parameters (found in the prhs array) are read only; your MEX-file should not modify them. Changing data in an input parameter may produce undesired side effects.
You also must take care when using an input parameter to create output data or any data used locally in your MEX-file. This is because of the way MATLAB handles MEX-file cleanup after processing. For an example, see the troubleshooting topic Incorrectly Constructing a Cell or Structure mxArray.
If you want to copy an input array into your local myData array, call mxDuplicateArray to make of copy of the input array before using it. For example:
mxArray *myData = mxCreateStructMatrix(1,1,nfields,fnames); mxSetField(myData,0,"myFieldName",mxDuplicateArray(prhs[0]));
Good programming practice requires you to validate inputs to your function. MATLAB provides mxIs* routines for this purpose. The mxIsClass function is a general-purpose way to test an mxArray.
For example, if your second input argument (identified by prhs[1]) must be a full matrix of real numbers, you can use the following statements to check this condition:
if(mxIsSparse(prhs[1]) ||
mxIsComplex(prhs[1]) ||
mxIsClass(prhs[1],"char")) {
mexErrMsgTxt("input2 must be full matrix of real values.");
}
This is not an exhaustive check. You may also need to test for structures, cell arrays, function handles, and MATLAB objects.
Although MATLAB performs cleanup of MEX-file variables, as described in Automatic Cleanup of Temporary Arrays, we recommend that binary MEX-files destroy their own temporary arrays and free their own dynamically allocated memory. It is more efficient to perform this cleanup in the source MEX-file than to rely on the automatic mechanism.
MATLAB provides functions, such as mxMalloc and mxFree, to manage memory. Use these functions instead of their standard C library counterparts because they let MATLAB manage memory and perform initialization and cleanup.
For information on how MATLAB allocates memory for arrays and data structures, see Memory Allocation in the Programming Fundamentals documentation.
You need to allocate memory for variables that your MEX-file uses. If the first input to your function (prhs[0]) is a string, in order to manipulate the string, you need to create a buffer buf of size buflen. The following statements declare these variables:
char *buf; int buflen;
The size of the buffer is dependent on the number of dimensions of your input array and the size of the data in the array. This statement calculates the size of buflen:
buflen = mxGetN(prhs[0])*sizeof(mxChar)+1;
Now we can allocate memory for buf:
buf = mxMalloc(buflen);
If buf is not returned as a plhs output parameter (as described in Cleaning Up and Exiting), then you should free its memory as follows:
mxFree(buf);
The mxGet* array access routines get references to the data in an mxArray. Use these routines to modify data in your MEX-file. Each function provides access to specific information in the mxArray. Some useful functions are mxGetData, mxGetPr, mxGetM, and mxGetString. Many of these functions have corresponding mxSet* routines to allow you to modify values in the array.
The following statements read the input string prhs[0] into a C-style string buf:
char *buf; int buflen; int status; buflen = mxGetN(prhs[0])*sizeof(mxChar)+1; buf = mxMalloc(buflen); status = mxGetString(prhs[0], buf, buflen);
Use the mexPrintf function, as you would a C printf function, to print a string in the MATLAB Command Window. Use the mexErrMsgIdAndTxt and mexWarnMsgIdAndTxt functions to print error and warning information in the Command Window.
For example, using the variables declared in the previous example, you can print the input string prhs[0] as follows:
if (mxGetString(prhs[0], buf, buflen) == 0) {
mexPrintf("The input string is: %s\n", buf);
}
The mexErrMsgIdAndTxt function prints error information and terminates your binary MEX-file. The mexWarnMsgIdAndTxt function prints information, but does not terminate the MEX-file.
if (mxIsChar(prhs[0])) {
if (mxGetString(prhs[0], buf, buflen) == 0) {
mexPrintf("The input string is: %s\n", buf);
}
else {
mexErrMsgIdAndTxt("MyProg:ConvertString",
"Could not convert string data.");
// exit MEX-file
}
}
else {
mexWarnMsgIdAndTxt("MyProg:InputString",
"Input should be a string to print properly.");
}
// continue with processingAs described in Allocating and Freeing Memory, destroy any temporary arrays and free any dynamically allocated memory, except if such an mxArray is returned in the output argument list, returned by mexGetVariablePtr, or used to create a structure. Also, never delete input arguments.
Use mxFree to free memory allocated by the mxCalloc, mxMalloc, or mxRealloc functions. Use mxDestroyArray to free memory allocated by the mxCreate* functions.
Binary MEX-files are subroutines produced from C/C++ or Fortran source code. They behave just like M-files and built-in functions. While M-files have a platform-independent extension .m, MATLAB identifies MEX-files by platform-specific extensions. The following table lists the platform-specific extensions for MEX-files.
Binary MEX-File Extensions
| Platform | Binary MEX-File Extension |
|---|---|
Linux®[a] (32-bit) | |
Linux x86-64 | |
Apple® Macintosh® (Intel®) | |
64-bit Sun™ Solaris™ SPARC® | |
Microsoft® Windows® (32-bit) | |
Windows x64 | |
[a] Linux is a registered trademark of Linus Torvalds. | |
You call MEX-files exactly as you call any M-function. For example, on a Windows platform, there is a binary MEX-file called histc.mexw32 in one of the MATLAB toolbox directories (matlabroot\toolbox\matlab\datafun) that performs a histogram count. The file histc.m contains the help text documentation. When you call histc from MATLAB, the dispatcher looks through the list of directories on the MATLAB search path. It scans each directory looking for the first occurrence of a file named histc with either the corresponding file name extension from the table or .m. When it finds one, it loads the file and executes it. Binary MEX-files take precedence over M-files when like-named files exist in the same directory. However, help text documentation still reads from the .m file.
You cannot use a binary MEX-file on a platform if it was compiled on a different platform. You must recompile the source code on the platform for which you want to use the MEX-file.
For MATLAB to be able to execute your C or Fortran functions, you must either put the compiled MEX-files containing those functions in a directory on the MATLAB path, or run MATLAB in the directory in which they reside. Functions in the current working directory are found before functions on the MATLAB path.
Type path to see what directories are currently included in your path. You can add new directories to the path either by using the addpath function, or by selecting File > SetPath to edit the path.
If you are using a Windows operating system and any of your binary MEX-files are on a network drive, be aware that file servers do not always report directory and file changes correctly. If you change any MEX-files that are on a network drive and you find that MATLAB is not using your latest changes, you can force MATLAB to look for the correct version of the file by changing directories away from and then back to the directory in which the files reside.
Routines in the MATLAB C and Fortran API that are prefixed with mx allow you to create, access, manipulate, and destroy mxArrays. Routines prefixed with mex perform operations back in the MATLAB environment.
The array access and creation library provides a set of array access and creation routines for manipulating MATLAB arrays. These subroutines, which are fully documented in the online API reference pages, always start with the prefix mx. For example, mxGetPi retrieves the pointer to the imaginary data inside the array.
Although most of the routines in the array access and creation library let you manipulate the MATLAB array, there are two exceptions—the IEEE® routines and memory management routines. For example, mxGetNaN returns a double, not an mxArray.
Routines that begin with the mex prefix perform operations back in the MATLAB environment. For example, the mexEvalString routine evaluates a string in the MATLAB workspace.
Note mex routines are only available in MEX-functions. |
[a] Linux is a registered trademark of Linus Torvalds.
![]() | Calling C and Fortran Programs from MATLAB® Command Line | MATLAB® Data | ![]() |
| © 1984-2008- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |