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 matrix.

arrayProduct multiplies an n-dimensional array, y, by a scalar value, x, and returns the results in array, z.

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 new 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 represent 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 mxGetPr function to point to the input matrix data.

/* create a pointer to the real data in the input matrix  */
inMatrix = mxGetPr(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 mxGetPr function to assign the outMatrix argument to plhs[0]

/* get a pointer to the real data in the output matrix */
outMatrix = mxGetPr(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 fileOpen the file in the editor.

Build Binary MEX-File

At the MATLAB command prompt, build the binary MEX-file.

mex arrayProduct.c

Test the MEX-File

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-file. To test the input variable, inputArg, and convert it to double, if necessary, use this code.

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

See Also

| | | | |

Related Examples

Was this topic helpful?