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:
- The ability to write C or C++ source code. You create these files with the MATLAB Editor.
- Compiler supported by MATLAB. For an up-to-date list of supported compilers, see the Supported and Compatible Compilers website.
- Functions in the C Matrix API and theC MEX API.
- mex build script.
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.
/*
- arrayProduct.c - example in MATLAB External Interfaces
- Multiplies an input scalar (multiplier)
- times a 1xN matrix (inMatrix)
- and outputs a 1xN matrix (outMatrix)
- The calling syntax is:
outMatrix = arrayProduct(multiplier, inMatrix)
- This is a MEX file for MATLAB. */
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
.
- Declare variables for the input arguments.
double multiplier; /* input scalar */
double inMatrix; / 1xN input matrix */ - Declare
ncols
for the size of the input matrix.
mwSize ncols; /* size of matrix */ - Declare the output argument,
outMatrix
.
double outMatrix; / output matrix */
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