Search All of the Math Forum:
Views expressed in these public forums are not endorsed by
Drexel University or The Math Forum.
|
|
|
|
Re: Making C++ objects persistent between mex calls, and robust.
Posted:
Jan 24, 2011 5:08 AM
|
|
"newuser asdf" wrote: > Iit works now (without Integer->Double->Integer conversions). > I know that the way I do all this (creating C++ memory leaks, that have to be cleaned up using Matlab...) is not very "clean" programming. But at least it works...
Good. It's worth noting that you are not creating C++ memory leaks; you are simply ensuring that MATLAB doesn't cause memory leaks if you accidentally clear a C++ object without first freeing the memory, by automatically freeing the memory when the object is cleared. There is nothing "unclean" about this; quite the opposite.
I posted the code for the MATLAB class side of things earlier. I'm now posting my code for the C++ side of things below. It includes error checking to make sure you don't convert any uint64 to a pointer, only the true C++ class pointers.
Hope it's useful. Oliver
// Define types #ifdef _MSC_VER typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #else #include <stdint.h> #endif
#define CLASS_HANDLE_SIGNATURE 0xa5a50f0f template<class base> class class_handle: public base { public: class_handle() : base() { signature = CLASS_HANDLE_SIGNATURE; } ~class_handle() { signature = 0; } bool isValid() { return (signature == CLASS_HANDLE_SIGNATURE); } private: uint32_t signature; };
template<class base> inline mxArray *convertPtr2Mat(class_handle<base> *ptr) { mxArray *out = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL); *((uint64_t *)mxGetData(out)) = reinterpret_cast<uint64_t>(ptr); return out; }
template<class base> inline class_handle<base> *convertMat2Ptr(const mxArray *in) { if (mxGetNumberOfElements(in) != 1 || mxGetClassID(in) != mxUINT64_CLASS || mxIsComplex(in)) mexErrMsgTxt("Input must be a real uint64 scalar."); class_handle<base> *ptr = reinterpret_cast<class_handle<base> *>(*((uint64_t *)mxGetData(in))); if (!ptr->isValid()) mexErrMsgTxt("Handle not valid."); return ptr; }
// Code for init_mex() - ISM3D is my C++ object class, but you use your own class_handle<ISM3D> *ism = new class_handle<ISM3D>;
// Code for clear_mex() class_handle<ISM3D> *ism = convertMat2Ptr<ISM3D>(prhs[0]); delete ism;
// Code for action_mex class_handle<ISM3D> *ism = convertMat2Ptr<ISM3D>(prhs[0]); ism->action();
|
|
|
|