This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Note: This page has been translated by MathWorks. Click here to see
To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

Create C Source MEX File

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.

This example uses the MATLAB Editor to write the source code and the MATLAB mex command to create the MEX function. The requirements for creating MEX files are listed in C Source MEX Files. 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.

ParameterDescription
nlhsNumber of output (left-side) arguments, or the size of the plhs array.
plhsArray of output arguments.
nrhsNumber of input (right-side) arguments, or the size of the prhs array.
prhsArray 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 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 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 matlabroot/extern/examples/mex. Open the file arrayProduct.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.

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

| | | | | |

Related Topics