Using C/C++ under Matlab (Part 3)

Author

Benoit Guilleminot

Keywords

Matlab, C, C++, Mex Files

Review Status

Draft


MEX Files : Basic Principles

The most fundamental structure used as an interface between Matlab internal types and C/C++ types is the mxArray structure. There are no real needs to go more in details into the description of the structure as basic functions allow us to manipulate data directly from C/C++ types.

The most useful function to start with is mxGetPr. It returns a direct (double*) pointer to the real part of any Matlab vector (and mxGetPi returns a pointer to the imaginary part). The array pointer returned can be used as any C/C++ array, i.e. read and written. To go through the array of values dimensions can be obtained easily by calls to mxGetM and mxGetN.

Some general principes are explained below.

1. mexFunction

The mexFunction is the main function called by Matlab when the function is executed. The function has four parameters : the two first ones represent outputs (left hand side) while the last ones are inputs (right hand side).

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    return;
}

2. Dealing with inputs

The third argument “nrhs” is an integer equal to the number of inputs. The fourth argument is a mxArray structure containing the effective list of inputs. In a simple case like

output = foo (1.2, [2.5 2.9], 3)

Then the “nrhs” variable will be equal to 3 and the last argument (prhs) is an array of mxArray structures.
The first element of this array, accessible via “prhs[0]” is a mxArray structure. Using mxGetPr(prhs[0]) returns a pointer to a double array of size(1,1) containing only one element “1.2”. mxGetM(prhs[0]) returns 1 as well as mxGetN(prhs[0]).

3. Dealing with outputs

The output system is similar. The different results to be returned are allocated using mxCreateXXX methods for instance (see below) and placed in the output array plhs.
The number of outputs is given by Matlab through the integer nlhs. It is important to know what is the left hand side of the calling equation.

Assume a simple pricing example, if the call is

[p1, p2] = pricer(...)

then nlhs is equal to 2 while in the following case

p1 = pricer(...)

nlhs is equal to 1.

Assuming I want to return two prices, say 100$ and 200$ that have been allocated in two mxArrays structures. Then the code would look like

//Check that syntax is correct, inputs, outputs, ...
mxArray * price1 = null; 
mxArray * price2 = null; 
double * ptrPrice1 = null;
double * ptrPrice2 = null;
 
price1 = mxCreateDoubleMatrix(1,1,mxREAL);
ptrPrice1 = mxGetPr(price1);
... (processing code) ...
 
if (nlhs > 1)
{
    price2 = mxCreateDoubleMatrix(1,1,mxREAL);
    ptrPrice2 = mxGetPr(price2);
    ... (processing code) ...
}
 
plhs[0] = price1;
if (nlhs > 1)
{
    plhs[1] = price2;
}

4. Overview of basic functions

A lot of functions are available and so the most basic ones are quoted here. What follows was directly taken from Matlab's help files (the exhaustive list of functions is available in help)

  • Creation/Allocation/Copy of memory
Name Role
mxMalloc Allocate dynamic memory using MATLAB memory manager
mxRealloc Reallocate memory
mxCalloc Allocate dynamic memory for array using MATLAB memory manager
mxDuplicateArray Make deep copy of array
  • A set of dedicated functions for data creation, all being prefixed by “mxCreateXXX” :
Name Role
mxCreateCharArray Create unpopulated N-D string mxArray
mxCreateDoubleMatrix Create 2-D, double-precision, floating-point mxArray initialized to 0
mxCreateDoubleScalar Create scalar, double-precision array initialized to specified value
mxCreateLogicalArray Create N-D logical mxArray initialized to false
mxCreateNumericArray Create unpopulated N-D numeric mxArray
mxCreateNumericMatrix Create numeric matrix and initialize data elements to 0
  • A set of getters (& corresponding setters) : the most useful are
Name Role
mxGetData Get pointer to data
mxGetDimensions Get pointer to dimensions array
mxGetElementSize Get number of bytes required to store each data element
mxGetM Get number of rows in mxArray
mxGetN Get number of columns in mxArray
mxGetNumberOfDimensions Get number of dimensions in mxArray
mxGetNumberOfElements Get number of elements in mxArray
mxGetPi Get imaginary data elements in mxArray
mxGetPr Get real data elements in mxArray
  • A set of isA :
Name Role
mxIsClass Determine whether mxArray is member of specified class
mxIsComplex Determine whether data is complex
mxIsDouble Determine whether mxArray represents data as double-precision, floating-point numbers
mxIsEmpty Determine whether mxArray is empty
mxIsFinite Determine whether input is finite
  • Liberation of memory :
Name Role
mxFree Free dynamic memory allocated by mxCalloc, mxMalloc, or mxRealloc
mxDestroyArray Free dynamic memory allocated by mxCreate* functions
  • Display / Error / Warning
Name Role
mexErrMsgTxt Issue error message and return to MATLAB prompt
mexEvalString Execute MATLAB command in caller's workspace
mexPrintf ANSI C printf-style output routine
mexWarnMsgIdAndTxt Issue warning message with identifier
mexWarnMsgTxt Issue warning message
  • Other
Name Role
mxAssert Check assertion value for debugging purposes
mxAssertS Check assertion value without printing assertion text
mxGetClassID Get class of mxArray
mxGetClassName Get class of mxArray as string

5. Calling a Matlab function (any m-file) from C/C++ code

It is quite easy to call Matlab functions (from any m-file) directly from your compiled code. You just have to respect the general format of input/outputs and use the function “mexCallMATLAB”. For example,

To generate one gaussian random variable

mxArray * output[1];
if (mexCallMATLAB(1, output, 0, null, "randn") != 0)
{
    //… free any allocated memory …
    mexErrMsgTxt("Error when calling randn");
}

The result will be stored in the array of mxArray named here output. To get access to it just use mxGetPr on output[0].

The same example with inputs

mxArray * output[1];
mxArray * intput[1];
double * inPtr = null;
 
input[0] =  mxCreateDoubleMatrix(1,2,mxREAL);
inPtr = (double*)mxGetPr(input[0]);
inPtr[0] = 512; // I want 512 random numbers
inPtr[1] = 1; 
 
if (mexCallMATLAB(1, output, 1, input, "randn") != 0)
{
    //… free any allocated memory …
    mexErrMsgTxt("Error when calling randn");
}

My input argument is the vector [512; 1].
My output argument will contain 512 random numbers generated by matlab function “randn”.

6. Basic Memory Management

Memory allocated using Matlab mx methods (like mxAlloc, MxCreateDoubleMatrix …) will be automatically freed by Matlab's Memory management system unless the MEX function ended abnormally (call to mexErrTxtMsg for instance). In such cases do not forget to introduce memory-freeing code before terminating your function.
In any case it is recommended to free memory as soon it is not needed anymore (using mxFree or mxDestroyArray) in order to improve performance and memory usage.

It seems that memory allocation using Matlab's memory system is slower than standard calls to C/C++ API like malloc or new. Choice is given to developers to go for the memory system they prefer, but particular attention must be paid to memory management in order to avoid leaks. Given the kind of computations/allocations that Matlab usually has to deal with, memory leaks would be very often lethal for the stability of the underlying operating system.

7. Outline

  1. Introduction
  2. Creating a project under Visual C++ Express 2008
  3. » Basic Principles «
  4. Advanced Principles
  5. Conclusion

Internal Links

Concepts
Tutorials
Tips
Related Articles

External links

References
Weblinks

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License