This example shows how to write a MEX file to call a C function
arrayProduct
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 the C 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.
arrayProduct
The following code defines the arrayProduct
function, which
multiplies a 1xn matrix y
by a scalar value
x
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]; } }
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.
#include "mex.h"
Save the file on your MATLAB path, for example, in c:\work
, and name it
arrayProduct.c
. The name of your MEX file is
arrayProduct
.
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 for
mexFunction
.
Parameter | Description |
---|---|
nlhs | Number of output (left-side) arguments, or the size of the
plhs array. |
plhs | Array of output arguments. |
nrhs | Number of input (right-side) arguments, or the size of the
prhs array. |
prhs | Array of input arguments. |
Verify the number of MEX file input and output arguments using the
nrhs
and nlhs
arguments.
To check for two input arguments, multiplier
and
inMatrix
, use this code.
if(nrhs != 2) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs", "Two inputs required."); }
Use this code to check for one output argument, the product
outMatrix
.
if(nlhs != 1) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs", "One output required."); }
Verify the argument types using the plhs
and
prhs
arguments. This code validates that
multiplier
, 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 by
prhs[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."); }
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.
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 the
int
declaration for variables n
and
i
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]; } }
Put the following variable declarations in
mexFunction
.
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.
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]);
To create the output argument, plhs[0]
, use the
mxCreateDoubleMatrix
function.
/* create the output matrix */ plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);
Use the mxGetDoubles
function to assign the
outMatrix
argument to plhs[0]
/* get a pointer to the real data in the output matrix */ outMatrix = mxGetDoubles(plhs[0]);
Pass the arguments to arrayProduct
.
/* call the computational routine */ arrayProduct(multiplier,inMatrix,outMatrix,ncols);
Compare your source file with arrayProduct.c
located in
.
Open the file matlabroot
/extern/examples/mexarrayProduct.c
in the editor.
For a C++ MEX file example using the MATLAB Data API, see arrayProduct.cpp
. For information about
creating MEX files with this API, see C++ MEX Functions.
At the MATLAB command prompt, build the function with the mex
command.
mex arrayProduct.c -R2018a
s = 5; A = [1.5, 2, 9]; B = arrayProduct(s,A)
B = 7.5000 10.0000 45.0000
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 to
double
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)
mex
| mexFunction
| mwSize
| mxCreateDoubleMatrix
| mxGetDoubles
| mxGetN
| mxGetScalar