Я написал пример, в котором Matlab вызывает код C ++ (EventProducer), который должен вызывать метод объекта Matlab (EventConsumer).
Но когда я запускаю свой тест см. ниже), mexCallMATLAB вызывает ошибку, потому что кажется, что он не может получить объект EventConsumer Matlab:
Undefined function 'consumeEvent' for input arguments of type 'EventProducer'.
Следует отметить, что если вы замените «provider.run1 ();» от «продюсер.рун2 (потребитель)»; (где вы передаете объект EventConsumer), все работает хорошо!
Любой совет? Заранее спасибо.
Классы C ++:
class EventConsumer {
public:
virtual ~EventConsumer() {}
virtual void consumeEvent() = 0;
protected:
EventConsumer() {}
};
class EventProducer {
public:
EventProducer::EventProducer() : mConsumer(nullptr) {}
virtual ~EventProducer() {}
void setConsumer(EventConsumer* consumer) {
mConsumer = consumer;
}
void run(EventConsumer* consumer = nullptr) {
if (consumer != nullptr)
consumer->consumeEvent();
else if (mConsumer != nullptr)
mConsumer->consumeEvent();
}
private:
EventConsumer* mConsumer;
};
Код Matlab:
classdef EventConsumer
methods
function this = EventConsumer(varargin)
end
function consumeEvent(varargin)
disp('Matlab consumeEvent called')
end
end
end
classdef EventProducer < handle
properties (SetAccess = private, Hidden = true)
objectHandle; % Handle to the underlying C++ class instance
end
methods
%% Constructor
function this = EventProducer(varargin)
this.objectHandle = EventProducer_mex('new', varargin{:});
end
%% Destructor
function delete(this)
EventProducer_mex('delete', this.objectHandle);
end
%% Other methods
function setConsumer(this, consumer)
EventProducer_mex('setConsumer', this.objectHandle, consumer);
end
function run1(this)
EventProducer_mex('run1', this.objectHandle);
end
function run2(this, consumer)
EventProducer_mex('run2', this.objectHandle, consumer);
end
end
end
producer = EventProducer();
consumer = EventConsumer();
producer.setConsumer(consumer);
producer.run1();
%% producer.run2(consumer);
delete(producer);
Файл Mex:
#include "../Class_Handle.hpp"
#include "EventProducer.h"
#include <iostream>
class MyEventConsumer : public EventConsumer {
public:
MyEventConsumer(const mxArray* matlabConsumer) {
mMatlabConsumer = matlabConsumer;
}
virtual ~MyEventConsumer() {}
void consumeEvent() {
std::cout << "C++ consumeEvent called" << std::endl;
mxArray* prhs[1];
prhs[0] = (mxArray*)mMatlabConsumer;
mexCallMATLAB(0, NULL, 1, prhs, "consumeEvent");
}
private:
const mxArray* mMatlabConsumer;
};
// The mex entry point
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
char fcn[64];
if (nrhs < 1 || mxGetString(prhs[0], fcn, sizeof(fcn))) {
mexErrMsgTxt("EventProducer_mex : First argument should be a function string less than 64 characters long.");
return;
}
// Constructor
if (! strcmp("new", fcn)) {
if (nlhs != 1 || nrhs != 1) {
mexErrMsgTxt("EventProducer_mex : 'new' function has wrong number of arguments.");
return;
}
// Return a handle to a new C++ instance
plhs[0] = convertPtr2Mat<EventProducer>(new EventProducer());
return;
}
// Destructor
if (! strcmp("delete", fcn)) {
if (nlhs != 0 || nrhs != 2) {
mexErrMsgTxt("EventProducer_mex : 'delete' function has wrong number of arguments.");
return;
}
// Destroy the C++ object
destroyObject<EventProducer>(prhs[1]);
return;
}
// Other methods
if (! strcmp("setConsumer", fcn)) {
if (nlhs != 0 || nrhs != 3) {
mexErrMsgTxt("EventProducer_mex : 'setConsumer' function has wrong number of arguments.");
return;
}
// Get the C++ EventProducer object, then call setConsumer
EventProducer* producer = convertMat2Ptr<EventProducer>(prhs[1]);
if (producer == NULL) {
mexErrMsgTxt("EventProducer_mex : 'setHandler' second argument should be a EventProducer class handle.");
return;
}
MyEventConsumer* consumer = new MyEventConsumer(prhs[2]);
producer->setConsumer(consumer);
return;
}
// run1
if (! strcmp("run1", fcn))
{
if (nlhs != 0 || nrhs != 2) {
mexErrMsgTxt("EventProducer_mex : 'run1' function has wrong number of arguments.");
return;
}
// Get the C++ EventProducer object, then call run
EventProducer* producer = convertMat2Ptr<EventProducer>(prhs[1]);
if (producer == NULL) {
mexErrMsgTxt("EventProducer_mex : 'run1' second argument should be a EventProducer class handle.");
return;
}
producer->run();
return;
}
// run2
if (! strcmp("run2", fcn)) {
if (nlhs != 0 || nrhs != 3) {
mexErrMsgTxt("EventProducer_mex : 'run2' function has wrong number of arguments.");
return;
}
// Get the C++ EventProducer object, then call run
EventProducer* producer = convertMat2Ptr<EventProducer>(prhs[1]);
if (producer == NULL) {
mexErrMsgTxt("EventProducer_mex : 'run2' second argument should be a EventProducer class handle.");
return;
}
MyEventConsumer* consumer = new MyEventConsumer(prhs[2]);
producer->run(consumer);
return;
}
mexErrMsgTxt("Function not recognized.");
}