Matrices in C S-Functions

MX Array Manipulation

S-functions can manipulate mxArrays using the standard MATLAB® API functions. (See C/C++ Matrix Library API for a list of functions.) In general, if your S-function is declared exception free by passing the SS_OPTION_EXCEPTION_FREE_CODE option to ssSetOptions (see Exception Free Code in Error Handling), it should avoid MATLAB API functions that throw exceptions (i.e., long jump), such as mxCreateDoubleMatrix. Otherwise, the S-function can use any of the listed functions.

If you have Simulink® Coder™, it supports a subset of the mxArray manipulation functions when generating noninlined code for an S-function. For a list of supported functions, see Write Noninlined S-Functions.

Calls to the macro ssGetSFcnParam return a pointer to an mxArray, which can be used with the mxArray manipulation functions. If your S-function contains S-function parameters, use the mxArray manipulation functions in the mdlCheckParameters method to check the S-function parameter values. See the S-function sfun_runtime3.csfun_runtime3.c for an example

In this S-function, the following lines check that the first S-function parameter is a character array with a length greater than or equal to two.

if (!mxIsChar(ssGetSFcnParam(S, 0)) ||
     (nu=mxGetNumberOfElements(ssGetSFcnParam(S, 0))) < 2) {
     ssSetErrorStatus(S,"1st parameter to S-function must be a "
       "string of at least 2 '+' and '-' characters");
     return;
}

Memory Allocation

When you create an S-function, you might need to allocate memory for each instance of your S-function. The standard MATLAB API memory allocation routines mxCalloc and mxFree should not be used with C MEX S-functions, because these routines are designed to be used with MEX files that are called from the MATLAB environment and not the Simulink environment. The correct approach for allocating memory is to use the stdlib.h library routines calloc and free. In mdlStart, allocate and initialize the memory

UD *ptr = (UD *)calloc(1,sizeof(UD));

where UD, in this example, is a data structure defined at the beginning of the S-function. Then, place the pointer to it either in the pointer work vector

ssSetPWorkValue(S, 0, ptr);

or attach it as user data.

ssSetUserData(S,ptr); 

In mdlTerminate, free the allocated memory. For example, if the pointer was stored in the user data

UD *prt = ssGetUserData(S);
free(prt);
Was this topic helpful?