How can I call MATLAB object's method from C++?
Show older comments
Hi
Using bellow command we can easily call a function(here "foo.m") which was wrote in MATLAB from C++.
mexCallMATLAB(nlhs, plhs, nrhs, prhs, "foo")
But what if "foo" is a method of a class?
classdef Foo < handle
...
function out = foo(obj, in)
end
end
Is there any straightforward or trick to call member function from C++?
1 Comment
James Tursa
on 13 Oct 2017
Accepted Answer
More Answers (1)
James Tursa
on 18 Oct 2017
Edited: James Tursa
on 18 Oct 2017
Here is some code based loosely on your singleton design, with an example run. Note that if you clear the mex routine, then the obj address is of course lost and you must re-set it. Maybe you are clearing your mex routine between calls inadvertently?
#include "mex.h"
class MatlabModuleInterface
{
public:
mxArray *obj;
static MatlabModuleInterface& GetInstance()
{
static MatlabModuleInterface instance;
return instance;
}
bool MatlabModuleInterface::Display()
{
int nlhs = 0, nrhs = 1;
mxArray *plhs[1], *prhs[1];
prhs[0] = MatlabModuleInterface::GetInstance().obj;
mexPrintf("Using obj = %p\n",prhs[0]);
if( mexCallMATLAB(nlhs, plhs, nrhs, prhs, "foo_disp") ) {
mexErrMsgTxt("mexCallMATLAB foo_disp failed");
}
return true;
}
bool MatlabModuleInterface::Set(mxArray *mx)
{
int nlhs = 0, nrhs = 2;
mxArray *plhs[1], *prhs[2];
prhs[0] = MatlabModuleInterface::GetInstance().obj;
prhs[1] = mx;
mexPrintf("Using obj = %p\n",prhs[0]);
if( mexCallMATLAB(nlhs, plhs, nrhs, prhs, "foo_set") ) {
mexErrMsgTxt("mexCallMATLAB foo_set failed");
}
return true;
}
};
int firstcall = 1;
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if( firstcall ) {
if( nrhs == 0 ) {
mexErrMsgTxt("Need one input of class Foo on 1st call.");
}
firstcall = 0;
mexPrintf("Setting obj = %p\n",prhs[0]);
MatlabModuleInterface::GetInstance().obj = (mxArray *)prhs[0];
return;
}
if( nrhs ) {
MatlabModuleInterface::GetInstance().Set((mxArray *)prhs[0]);
} else {
MatlabModuleInterface::GetInstance().Display();
}
}
The Foo class is:
classdef Foo < handle
properties
x
end
methods
function foo_disp(obj)
fprintf('The current value of x = %f\n',obj.x);
end
function foo_set(obj,y)
obj.x = y;
end
end
end
And a sample run is:
>> F = Foo
F =
Foo handle
Properties:
x: []
Methods, Events, Superclasses
>> singleton_design
??? Error using ==> singleton_design
Need one input of class Foo on 1st call.
>> singleton_design(F)
Setting obj = 0797F9D8
>> singleton_design
Using obj = 0797F9D8
The current value of x =
>> F.x = 5
F =
Foo handle
Properties:
x: 5
Methods, Events, Superclasses
>> singleton_design
Using obj = 0797F9D8
The current value of x = 5.000000
>> singleton_design(7)
Using obj = 0797F9D8
>> singleton_design
Using obj = 0797F9D8
The current value of x = 7.000000
>> clear singleton_design
>> singleton_design
??? Error using ==> singleton_design
Need one input of class Foo on 1st call.
>> singleton_design(F)
Setting obj = 0797F9D8
>> singleton_design
Using obj = 0797F9D8
The current value of x = 7.000000
>> clear F
>> singleton_design
Using obj = 0797F9D8
??? Error using ==> singleton_design
Undefined function or method 'foo_disp' for input arguments of type 'char'.
For that last singleton_design call, the obj address within the MatlabModuleInterface class is invalid, and anything could have happened including a MATLAB crash. This is an example of the inherent instability of the C code design ... you are relying on the Foo variable address contained in obj to remain valid and hope that the user doesn't do anything to make it invalid.
Categories
Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!