Create C Source MEX File arrayProduct.c
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.
mexbuild 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 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];
}
}
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.
#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.
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 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 MEX File Input and Output Parameters
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.");
}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 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];
}
}
Declare Variables for Computational Routine
Put the following variable declarations in
mexFunction.
Declare variables for the input arguments.
double multiplier; /* input scalar */ double *inMatrix; /* 1xN input matrix */
Declare
ncolsfor 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 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]);
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
.
Open the file matlabroot/extern/examples/mexarrayProduct.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 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)
See Also
mex | mexFunction | mxCreateDoubleMatrix