Create a C++ MEX Source File
Here is how to create a basic C++ MEX function. This function just adds an offset to each element of an input array to demonstrate basic input and output. For a more detailed discussion on creating MEX function source code, see Structure of C++ MEX Function and related topics.
Create Source File
Using your editor, create a file with a .cpp
extension and add
commented instructions. For example, MyMEXFunction.cpp
.
/* MyMEXFunction
* c = MyMEXFunction(a,b);
* Adds offset argument a to each element of double array b and
* returns the modified array c.
*/
Add Required Header Files
For C++ MEX functions, add these header files.
/* MyMEXFunction
* c = MyMEXFunction(a,b);
* Adds offset argument a to each element of double array b and
* returns the modified array c.
*/
#include "mex.hpp"
#include "mexAdapter.hpp"
Using Convenience Definitions
Optionally specify the namespace for matlab::data
and define
other conveniences.
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */ #include "mex.hpp" #include "mexAdapter.hpp" using namespace matlab::data; using matlab::mex::ArgumentList;
Define MexFunction Class
All C++ MEX functions are implemented as a class named
MexFunction
. This class must derive from matlab::mex::Function
.
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */ #include "mex.hpp" #include "mexAdapter.hpp" using namespace matlab::data; using matlab::mex::ArgumentList; class MexFunction : public matlab::mex::Function { };
Define operator()
All MexFunction
classes must override the function call
operator, operator()
, to accept two arguments of type matlab::mex::ArgumentList
. These arguments contain the inputs and
outputs.
/* MyMEXFunction
* c = MyMEXFunction(a,b);
* Adds offset argument a to each element of double array b and
* returns the modified array c.
*/
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
public:
void operator()(ArgumentList outputs, ArgumentList inputs) {
}
};
Add Member Function to Check Arguments
Test to see if the arguments are of the correct type and size. If tests fail, call
the MATLAB®
error
function.
/* MyMEXFunction
* c = MyMEXFunction(a,b);
* Adds offset argument a to each element of double array b and
* returns the modified array c.
*/
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
public:
void operator()(ArgumentList outputs, ArgumentList inputs) {
}
void checkArguments(ArgumentList outputs, ArgumentList inputs) {
// Get pointer to engine
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
// Get array factory
ArrayFactory factory;
// Check offset argument: First input must be scalar double
if (inputs[0].getType() != ArrayType::DOUBLE ||
inputs[0].getNumberOfElements() != 1)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("First input must be scalar double") }));
}
// Check array argument: Second input must be double array
if (inputs[1].getType() != ArrayType::DOUBLE)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("Input must be double array") }));
}
// Check number of outputs
if (outputs.size() > 1)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("Only one output is returned") }));
}
}
};
Implement Computation
Get the scalar offset and assign it to a const
double
. Get the input array and move it to a
matlab::data::TypedArray<double>
to work on the array. Add
the offset to each element in the array and assign the modified array to the output
variable.
/* MyMEXFunction
* c = MyMEXFunction(a,b);
* Adds offset argument a to each element of double array b and
* returns the modified array c.
*/
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
public:
void operator()(ArgumentList outputs, ArgumentList inputs) {
checkArguments(outputs, inputs);
const double offSet = inputs[0][0];
TypedArray<double> doubleArray = std::move(inputs[1]);
for (auto& elem : doubleArray) {
elem += offSet;
}
outputs[0] = doubleArray;
}
void checkArguments(ArgumentList outputs, ArgumentList inputs) {
// Get pointer to engine
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
// Get array factory
ArrayFactory factory;
// Check offset argument: First input must be scalar double
if (inputs[0].getType() != ArrayType::DOUBLE ||
inputs[0].getType() == ArrayType::COMPLEX_DOUBLE ||
inputs[0].getNumberOfElements() != 1)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("First input must be scalar double") }));
}
// Check array argument: Second input must be double array
if (inputs[1].getType() != ArrayType::DOUBLE ||
inputs[1].getType() == ArrayType::COMPLEX_DOUBLE)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("Input must be double array") }));
}
// Check number of outputs
if (outputs.size() > 1) {
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("Only one output is returned") }));
}
}
};
Setup and Build
After installing a supported compiler, use the mex
command to
build your MEX function.
mex -setup c++ mex MyMEXFunction.cpp
For more information on building MEX functions, see Build C++ MEX Programs.
Call MEX Function
Call your MEX function from MATLAB.
b = MyMEXFunction(11.5, rand(1000));
See Also
mex
| matlab::mex::Function
| matlab::mex::ArgumentList