Create C Source MEX File arrayProduct.c - MATLAB & Simulink (original) (raw)

This example shows how to write a MEX file to call a C functionarrayProduct in MATLABĀ® using a MATLAB array defined in the C Matrix API. You can view the complete source file here.

To use this example, you need:

If you want to use your own C development environment, see Custom Build with MEX Script Options for more information.

C function arrayProduct

The following code defines the arrayProduct function, which multiplies a 1xn matrix y by a scalar valuex and returns the results in array z. You can use these same C statements in a C++ application.

void arrayProduct(double x, double *y, double *z, int n) { int i;

for (i=0; i<n; i++) { z[i] = x * y[i]; } }

Create Source File

Open MATLAB Editor, create a file, and document the MEX file with the following information.

/*

Add the C/C++ header file, mex.h, containing the MATLAB API function declarations.

Save the file on your MATLAB path, for example, in c:\work, and name itarrayProduct.c. The name of your MEX file isarrayProduct.

Create Gateway Routine

Every C program has a main() function. MATLAB uses the gateway routine, mexFunction, as the entry point to the function. Add the following mexFunction code.

/* The gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray prhs[]) { / variable declarations here */

/* code here */ }

This table describes the input parameters formexFunction.

Parameter Description
nlhs Number of output (left-side) arguments, or the size of theplhs array.
plhs Array of output arguments.
nrhs Number of input (right-side) arguments, or the size of theprhs array.
prhs Array of input arguments.

Verify MEX File Input and Output Parameters

Verify the number of MEX file input and output arguments using thenrhs and nlhs arguments.

To check for two input arguments, multiplier andinMatrix, use this code.

if(nrhs != 2) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs", "Two inputs required."); }

Use this code to check for one output argument, the productoutMatrix.

if(nlhs != 1) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs", "One output required."); }

Verify the argument types using the plhs andprhs arguments. This code validates thatmultiplier, represented by prhs[0], is a scalar.

/* 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."); }

This code validates that inMatrix, represented byprhs[1], is type double.

if( !mxIsDouble(prhs[1]) || mxIsComplex(prhs[1])) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble", "Input matrix must be type double."); }

Validate that inMatrix is 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."); }

Create Computational Routine

Add the arrayProduct code. This function is your_computational routine_, the source code that performs the functionality you want to use in MATLAB.

void arrayProduct(double x, double *y, double *z, int n) { int i;

for (i=0; i<n; i++) { z[i] = x * y[i]; } }

A computational routine is optional. Alternatively, you can place the code within the mexFunction function block.

Write Code for Cross-Platform Flexibility

MATLAB provides a preprocessor macro, mwsize, that represents size values for integers, based on the platform. The computational routine declares the size of the array as int. Replace theint declaration for variables n andi with mwsize.

void arrayProduct(double x, double *y, double *z, mwSize n) { mwSize i;

for (i=0; i<n; i++) { z[i] = x * y[i]; } }

Declare Variables for Computational Routine

Put the following variable declarations inmexFunction.

Later you assign the mexFunction arguments to these variables.

Read Input Data

To read the scalar input, use the mxGetScalar function.

/* get the value of the scalar input */ multiplier = mxGetScalar(prhs[0]);

Use the mxGetDoubles function to point to the input matrix data.

/* create a pointer to the real data in the input matrix */ inMatrix = mxGetDoubles(prhs[1]);

Use the mxGetN function to get the size of the matrix.

/* get dimensions of the input matrix */ ncols = mxGetN(prhs[1]);

Prepare Output Data

To create the output argument, plhs[0], use themxCreateDoubleMatrix function.

/* create the output matrix */ plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);

Use the mxGetDoubles function to assign theoutMatrix argument to plhs[0]

/* get a pointer to the real data in the output matrix */ outMatrix = mxGetDoubles(plhs[0]);

Perform Calculation

Pass the arguments to arrayProduct.

/* call the computational routine */ arrayProduct(multiplier,inMatrix,outMatrix,ncols);

View Complete Source File

Compare your source file with arrayProduct.c located in_`matlabroot`_/extern/examples/mex. Open the file arrayProduct.c in the editor.

For a C++ MEX file example using the MATLAB Data API for C++, see arrayProduct.cpp. For information about creating MEX files with this API, see C++ MEX Functions.

Build MEX Function

At the MATLAB command prompt, build the function with the mex command.

mex arrayProduct.c -R2018a

Test the MEX Function

s = 5; A = [1.5, 2, 9]; B = arrayProduct(s,A)

B = 7.5000 10.0000 45.0000

Validate MEX File Input Arguments

It is good practice to validate the type of a MATLAB variable before calling a MEX function. To test the input variable, inputArg, and convert it todouble if necessary, use this code.

s = 5; A = [1.5, 2, 9]; inputArg = int16(A); if ~strcmp(class(inputArg),'double') inputArg = double(inputArg); end B = arrayProduct(s,inputArg)

See Also

mex | mexFunction | mxCreateDoubleMatrix

Topics