Main Content

Structure of C++ MEX Function

MEX Function Design

A C++ MEX function is a class that overrides the function call operator, operator() to create a function object or functor. These objects behave like MATLAB® functions that can accept inputs and return outputs.

Header Files

Include these header files:

  • mex.hpp — Include this file for the C++ MEX API.

  • mexAdapter.hpp — Include this file once for the implementation of MexFunction class

Namespaces

The C++ MEX APIs are contained in these namespaces:

  • matlab::mex — MEX interface

  • matlab::data — MATLAB Data API

  • matlab::engine — Engine API for C++

Entry Point

Define a C++ MEX function as a class named MexFunction that derives from the matlab::mex::Function class. The MexFunction class overrides the virtual operator() of the matlab::mex::Function class.

#include "mex.hpp"
#include "mexAdapter.hpp"

class MexFunction : public matlab::mex::Function {
public:
    void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) {
        // check input arguments
        // implement function
        ...
    }
}

Passing Arguments

MATLAB passes each input argument as a matlab::data::Array in the matlab::mex::ArgumentList container. Access each input by indexing into the ArgumentList array. For example, inputs[0] is the first input, inputs[1] is the second, and so on. The number of elements in the inputs variable equals the number of input arguments passed to the MEX function when the function is called. ArgumentList support iterators and can be used in range-based for loops.

Assign the output arguments to the output variable. For example, outputs[0] is the first output assigned, outputs[1] is the second, and so on. The number of elements in the outputs variable equals the number of outputs assigned when the function is called.

It is often useful to assign input arguments to other types of MATLAB data arrays. Specific types like matlab::data::TypedArray<T> or matlab::data::CharArray provide additional functionality like iterators and converter functions. Choose the type that matches the type of the input.

For example, the following MEX function assigns the input array to a matlab::data::TypedArray<double>. This array type supports the use of a range-based for loop, which is used to multiply each element in the array by 2. The modified array is returned in the outputs variable.

#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) {

        // Validate arguments
        checkArguments(outputs, inputs);

        // Implement function
        TypedArray<double> doubleArray = std::move(inputs[0]);
        for (auto& elem : doubleArray) {
            elem *= 2;
        }

        // Assign outputs
        outputs[0] = doubleArray;
    }

    void checkArguments(ArgumentList outputs, ArgumentList inputs) {
        std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
        ArrayFactory factory;
        if (inputs[0].getType() != ArrayType::DOUBLE ||
            inputs[0].getType() == ArrayType::COMPLEX_DOUBLE)
        {
            matlabPtr->feval(u"error", 0, 
                std::vector<Array>({ factory.createScalar("Input must be double array") }));
        }

        if (outputs.size() > 1) {
            matlabPtr->feval(u"error", 0, 
                std::vector<Array>({ factory.createScalar("Only one output is returned") }));
        }
    }
};

Build and run the MEX function.

mex timesTwo.cpp
timesTwo(1:10)
ans =

     2     4     6     8    10    12    14    16    18    20

For more information on validating arguments, see Handle Inputs and Outputs.

Class Constructor and Destructor

Calling the MEX function from MATLAB instantiates the MexFunction class. For example, this MATLAB statement creates an instance of the MexFunction class defined by the myMEXFunction.cpp file.

output = myMEXFunction(input);

This instance continues to exist until you call the MATLAB clear mex command.

Implementing a class constructor and destructor provides a way to perform certain tasks when constructing the MexFunction object. For example, this code snippet opens a text file for reading in the constructor and closes the file in the destructor.

#include "mex.hpp"
#include "mexAdapter.hpp"
#include <fstream> 

using matlab::mex::ArgumentList;

class MexFunction : public matlab::mex::Function {
    std::ifstream inFile;

public:
    MexFunction() {
        inFile.open("someTextFile.txt");
    }

    ~MexFunction() {
         inFile.close();
    }

    void operator()(ArgumentList outputs, ArgumentList inputs) {
        ....
    }
};

For an example, see Manage External Resources from MEX Functions.

See Also

|

Related Topics