Search All of the Math Forum:
Views expressed in these public forums are not endorsed by
Drexel University or The Math Forum.
|
|
mathias
Posts:
6
Registered:
1/20/10
|
|
Re: Making C++ objects persistent between mex calls, and robust.
Posted:
Jul 6, 2011 2:31 AM
|
|
Just for the record, in order to complete what has been proposed :
I faced the same issue (which is why I ended up on this thread).
I just want to point out a side problem :
the reinterpret_cast loose the type_id and therefore handling object of a class hierarchy through the mother_class and dynamic_cast is made difficult.
For instance, imagine the class hierachy : class A {}; class B : public A{}; class C : public B {};
imagine in "mex_function1 " you create B * pB = new B(); C * pC = new C();
then you send the pointers to matlab, and provide the pointer back to another mex function "mex_function2", and want to use a A * interface : A * pA = createObjectPointerFromMxArray(prhs[0)
and later on :
pB * = dynamic_cast<B*>(pA) ; if(NULL!=pB) etc .....
This will not work, since the type_id of the object is lost
As a consequence, I ended up creating a class for storing object.
The class mainly contains a pointer to a map :
class storage { public : storage();
object * retrieveObject(string key); string registerObject(object * inObject);
private : static map<string,object * > * _myMap; }
the storage is used for registering and retrieving objects through a key (string). What is transmitted to matlab and then back to mexes is just the string key. This permits keeping the type_id of created objects.
Then the storage is made global, basically using the following constructor
// static init map<string,object * > storage::_myMap =NULL;
// constructor storage:storage() { if(NULL == _myMap) { // look for the global adress mxArray * mxContainer = mexGetVariable("global","globalObjectStorageAdress");
if( NULL == mxContainer) { mexPrintf("Storage container does not exist, creating one\n");
_myMap = new map<string,object * >; mxContainer = createMxArrayFromObjectPointer(_matlabStorage); int status = mexPutVariable("global","globalObjectStorageAdressr",mxContainer);
std::cout << "status " << status; } else { mexPrintf("Using existing storage\n");
_myMap = createObjectPointerFromMxArray<map<string,object * >>(mxContainer); }
} } I hope this can help.
Here are the two helpers written by a collegue of mine
template <typename TOBJECT> TOBJECT * createObjectPointerFromMxArray(const mxArray * inArray) throw (LOCException) { if (mxGetClassID(inArray) != mxINDEX_CLASS) throw LOCException("The input mxArray must be of type mxUINT32_CLASS or mxUINT64_CLASS to store an object pointer."); if ((mxGetM(inArray) != 1) || (mxGetM(inArray) != 1)) throw LOCException("The input mxArray must be scalar to store an object pointer.");
return *(reinterpret_cast<TOBJECT**>(mxGetData(inArray))); }
template <typename TOBJECT> mxArray * createMxArrayFromObjectPointer(TOBJECT * ptrObject) { mxArray * outArray = mxCreateNumericMatrix(1, 1, mxINDEX_CLASS, mxREAL); TOBJECT * * ptrData = reinterpret_cast<TOBJECT**>(mxGetData(outArray)); *ptrData = ptrObject; return outArray; }
As
|
|
|
|