External Interfaces

A First Example -- Passing a Scalar

Let's look at a simple example of C code and its MEX-file equivalent. Here is a C computational function that takes a scalar and doubles it.

• ```#include <math.h>
void timestwo(double y[], double x[])
{
y[0] = 2.0*x[0];
return;
}
```

Below is the same function written in the MEX-file format.

• ```/*
* =============================================================
* timestwo.c - example found in API guide
*
* Computational function that takes a scalar and doubles it.
*
* This is a MEX-file for MATLAB.
* Copyright (c) 1984-2000 The MathWorks, Inc.
* =============================================================
*/

/* \$Revision: 1.8 \$ */

#include "mex.h"

void timestwo(double y[], double x[])
{
y[0] = 2.0*x[0];
}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[])
{
double *x, *y;
int mrows, ncols;

/* Check for proper number of arguments. */
if (nrhs != 1) {
mexErrMsgTxt("One input required.");
} else if (nlhs > 1) {
mexErrMsgTxt("Too many output arguments");
}

/* The input must be a noncomplex scalar double.*/
mrows = mxGetM(prhs[0]);
ncols = mxGetN(prhs[0]);
if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) ||
!(mrows == 1 && ncols == 1)) {
mexErrMsgTxt("Input must be a noncomplex scalar double.");
}

/* Create matrix for the return argument. */
plhs[0] = mxCreateDoubleMatrix(mrows,ncols, mxREAL);

/* Assign pointers to each input and output. */
x = mxGetPr(prhs[0]);
y = mxGetPr(plhs[0]);

/* Call the timestwo subroutine. */
timestwo(y,x);
}
```

In C, function argument checking is done at compile time. In MATLAB, you can pass any number or type of arguments to your M-function, which is responsible for argument checking. This is also true for MEX-files. Your program must safely handle any number of input or output arguments of any supported type.

To compile and link this example source file at the MATLAB prompt, type

• ``````mex timestwo.c
``````

This carries out the necessary steps to create the MEX-file called `timestwo` with an extension corresponding to the platform on which you're running. You can now call `timestwo` as if it were an M-function.

• ```x = 2;
y = timestwo(x)
y =
4
```

You can create and compile MEX-files in MATLAB or at your operating system's prompt. MATLAB uses `mex.m`, an M-file version of the `mex` script, and your operating system uses `mex.bat` on Windows and `mex.sh` on UNIX. In either case, typing

• ```mex ```filename
``````

at the prompt produces a compiled version of your MEX-file.

In the above example, scalars are viewed as 1-by-1 matrices. Alternatively, you can use a special API function called `mxGetScalar` that returns the values of scalars instead of pointers to copies of scalar variables. This is the alternative code (error checking has been omitted for brevity).

• ```/*
* =============================================================
* timestwoalt.c - example found in API guide
*
* Use mxGetScalar to return the values of scalars instead of
* pointers to copies of scalar variables.
*
* This is a MEX-file for MATLAB.
* Copyright (c) 1984-2000 The MathWorks, Inc.
* =============================================================
*/

/* \$Revision: 1.5 \$ */

#include "mex.h"

void timestwo_alt(double *y, double x)
{
*y = 2.0*x;
}

void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double *y;
double x;

/* Create a 1-by-1 matrix for the return argument. */
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);

/* Get the scalar value of the input x. */
/* Note: mxGetScalar returns a value, not a pointer. */
x = mxGetScalar(prhs[0]);

/* Assign a pointer to the output. */
y = mxGetPr(plhs[0]);

/* Call the timestwo_alt subroutine. */
timestwo_alt(y,x);
}
```

This example passes the input scalar `x` by value into the `timestwo_alt` subroutine, but passes the output scalar `y` by reference.

 Examples of C MEX-Files Passing Strings