Search code examples
c++cmatlabmethodsmex

Calling methods of C++ class in MEX from MATLAB


I have a DLP kit which I need to control via MATLAB using a C++ API.

Say, I have functions/methods using C/C++ for {load_data, load_settings,display_data} in a mex file named dlp_controller.cpp/.c.

I know I can call dlp_controller(); with MATLAB.

Is there a way I can call the method of this mex from MATLAB directly?

Say my dlp_controller.cpp mex looks as:

class dlp{ ... }
dlp::dlp{ ... }
dlp::load_data{ ... }
dlp::load_settings{ ... }
dlp::display_data{ ... }

void mexFunction(int nlhs, mxArray *[],int nrhs, const mxArray *prhs[]{ ... }

Can I somehow call the methods like dlp_controller.load_data from MATLAB? NOTE: A workaround can be to send a variable to dlp_controller and call the function internally using that and the data passed.


Solution

  • AFAIK, there's no straightforward way to do this, because the mexFunction interface is rather flat. However, there are a few different workarounds I can think of that should get you close. Choose the best one depending on your needs.

    1. The easiest is to create a global instance of the dlp class in your mex function. Make the first parameter of the mex function call a string that instructs which member function of the global object is to be invoked. The obvious drawback is that you've turned your mex function into a singleton.

    2. If you need more than one dlp instance, you could create some global container in the mex function, std::map<std::string, dlp> for instance, and then refer to each dlp instance by some name from within MATLAB. For instance, to create a new instance you'd call the mex function with a name that doesn't already exist in the map. Then you could call the mex function with this name, a string indicating which member function to invoke, and any parameters to be passed to the member function. Also set up some convention by which you can erase a dlp instance from the map.

    3. Similar to the second solution, instead of naming the dlp instances you could return handles to each instance. For instance, create a global std::set<dlp *> and when you have the mex function create a new dlp instance, add it to the set and return a copy of the pointer to the allocated object to MATLAB (stick it in a scalar variable of type mxUINT64_CLASS). Subsequent calls to invoke member functions on that object will pass this handle variable to the mex function from MATLAB, you'll cast it appropriately within the mex file, find it within the set and invoke member functions.

    None of these methods are particularly pretty, but these are the only ways I know of to invoke member functions of a C++ class from within a mex file.