classHandleMtoC.h 4.0 KB

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