Search code examples
cmatlabmexmatlab-coder

Is there any difference between a mex file and a function called with coder.ceval?


related

My goal is to use a mix of C code and Matlab code, and ultimately have the whole thing run in C by using the Coder tool. I've found 2 ways of incorporating C into Matlab, writing a Mex file, and using coder.ceval on a C program.

Is there any difference in these 2 methods, beyond just calling syntax?


Solution

  • I'll compare creating a hand-written MEX file against using MATLAB Coder to integrate custom C code using coder.ceval.

    Similarities

    In both cases, a MEX file can be produced that you can call in MATLAB like any other MATLAB function. A hand-written MEX function will be compiled using the mex command from C source code you write. With MATLAB Coder the MEX file will be automatically generated from MATLAB code that calls your C code via coder.ceval using either the codegen command or the MATLAB Coder App.

    Some Basic Differences

    (note I use C throughout, but C++ can be used for MEX files as well)

    • When writing a MEX file, it is necessary to manually move your data between mxArray values and native C types. You'll need to use the MEX library and the C/C++ Matrix Library to do this. If coder.ceval is used, a MEX file can be auto-generated from your MATLAB code that does this data marshalling for you.
    • A single hand-written MEX file can be made to work with a variety of MATLAB data types. MATLAB Coder requires the type, size (arrays can also be made variable-size), and complexity of each argument to be declared. For example, if you want a MEX file that takes double and single values for a given input, then one MEX file must be generated for each input type.
    • With a handwritten MEX file, once the data is retrieved from the mxArray values provided by MATLAB, arbitrary C code can be written to manipulate it. coder.ceval requires that you write MATLAB Coder compatible MATLAB code to call the C functions using the external code interfaces it provides. For functions with simple interfaces, e.g. those taking numeric arrays, strings, etc., this can be simple. For those that take other datatypes, more advanced tools like coder.opaque, coder.cstructname and custom enumeration definitions must be used which can take time. One needs to weigh the cost of developing this interface for MATLAB Coder versus learning and using the MATLAB libraries mentioned in the first bullet.
    • If you eventually want to use the code in C outside of MATLAB, with MATLAB Coder and coder.ceval, the target can simply be changed from MEX to a standalone target like a static or dynamic library or executable. With a handwritten MEX file, one typically factors the C code so that the MEX interface, mexFunction, is separate from the C functional kernel. Then, this kernel can be called outside of MEX. If you are planning to use MATLAB Coder anyway, you'll have to integrate the MATLAB Coder code with this kernel somehow.

    If the code is to be used with MATLAB Coder eventually, calling MEX files using Coder when the target is MEX requires using coder.extrinsic. They also cannot be called directly in standalone targets. Instead, the C computational kernel underlying the MEX file needs to be integrated with the generated code either during code generation using coder.ceval or after code generating using a traditional C development environment.

    Factors to Consider When Deciding

    1. Do the benefits of integrating the C code early using MATLAB Coder and having the MEX interface auto-generated outweigh the work required to use the MATLAB Coder external code interfaces versus a hand-written MEX file?
    2. Is integrating the external C code using coder.ceval easier or harder than writing a MEX file that exposes it to MATLAB and then later integrating your MATLAB Coder generated code with the computational kernel underlying your MEX file?