classHandleMtoC.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /**
  2. * @file classHandleMtoC.h
  3. * @brief Generic class to pass C++ objects to matlab (Interface and inline implementations)
  4. * @author Alexander Freytag
  5. * @date 19-12-2013 (dd-mm-yyyy)
  6. */
  7. #ifndef _NICE_CLASSHANDLEMTOCINCLUDE
  8. #define _NICE_CLASSHANDLEMTOCINCLUDE
  9. // STL includes
  10. #include <mex.h>
  11. #include <stdint.h>
  12. #include <iostream>
  13. #include <string>
  14. #include <cstring>
  15. #include <typeinfo>
  16. #define CLASS_HANDLE_SIGNATURE 0xFF00F0A3
  17. /**
  18. * @class ClassHandle
  19. * @brief Generic class to pass C++ objects to matlab
  20. * @author Alexander Freytag
  21. */
  22. template<class objectClass> class ClassHandle
  23. {
  24. private:
  25. //!
  26. uint32_t i_mySignature;
  27. //! typeid.name of object class we refere to
  28. std::string s_myName;
  29. //! the actual pointer to our C++ object
  30. objectClass* p_myPtr;
  31. public:
  32. /**
  33. * @brief standard constructor
  34. *
  35. * @param ptr pointer to the c++ object
  36. */
  37. ClassHandle ( objectClass* p_ptr ) : p_myPtr(p_ptr), s_myName( typeid(objectClass).name() )
  38. {
  39. i_mySignature = CLASS_HANDLE_SIGNATURE;
  40. }
  41. /**
  42. * @brief standard destructor
  43. */
  44. ~ClassHandle()
  45. {
  46. // reset internal variables
  47. i_mySignature = 0;
  48. // clearn up data
  49. delete p_myPtr;
  50. }
  51. /**
  52. * @brief check whether the class handle was initialized properly, i.e., we point to an actual object
  53. */
  54. bool isValid()
  55. {
  56. return ( (i_mySignature == CLASS_HANDLE_SIGNATURE) && !strcmp( s_myName.c_str(), typeid(objectClass).name() ) );
  57. }
  58. /**
  59. * @brief get the pointer to the actual object
  60. */
  61. objectClass * getPtrToObject()
  62. {
  63. return p_myPtr;
  64. }
  65. };
  66. ////////////////////////////////////////////
  67. // conversion methods //
  68. ////////////////////////////////////////////
  69. /**
  70. * @brief convert handle to C++ object into matlab usable data
  71. */
  72. template<class objectClass> inline mxArray *convertPtr2Mat(objectClass *ptr)
  73. {
  74. // prevent user from clearing the mex file! Otherwise, storage leaks might be caused
  75. mexLock();
  76. // allocate memory
  77. mxArray *out = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL);
  78. // convert handle do matlab usable data
  79. *((uint64_t *)mxGetData(out)) = reinterpret_cast<uint64_t>(new ClassHandle<objectClass>(ptr));
  80. return out;
  81. }
  82. /**
  83. * @brief convert matlab usable data referring to an object into handle to C++ object
  84. */
  85. template<class objectClass> inline ClassHandle<objectClass> *convertMat2HandlePtr(const mxArray *in)
  86. {
  87. // check that the given pointer actually points to a real object
  88. if ( ( mxGetNumberOfElements(in) != 1 ) ||
  89. ( mxGetClassID(in) != mxUINT64_CLASS ) ||
  90. mxIsComplex(in)
  91. )
  92. mexErrMsgTxt("Input must be a real uint64 scalar.");
  93. ClassHandle<objectClass> *ptr = reinterpret_cast<ClassHandle<objectClass> *>(*((uint64_t *)mxGetData(in)));
  94. if (!ptr->isValid())
  95. mexErrMsgTxt("Handle not valid.");
  96. return ptr;
  97. }
  98. /**
  99. * @brief convert matlab usable data referring to an object into direct pointer to the underlying C++ object
  100. */
  101. template<class objectClass> inline objectClass *convertMat2Ptr(const mxArray *in)
  102. {
  103. return convertMat2HandlePtr<objectClass>(in)->getPtrToObject();
  104. }
  105. /**
  106. * @brief convert matlab usable data referring to an object into direct pointer to the underlying C++ object
  107. */
  108. template<class objectClass> inline void destroyObject(const mxArray *in)
  109. {
  110. // clean up
  111. delete convertMat2HandlePtr<objectClass>(in);
  112. // storage is freed, so users can savely clear the mex file again at any time...
  113. mexUnlock();
  114. }
  115. #endif // _NICE_CLASSHANDLEMTOCINCLUDE