classHandleMtoC.h 3.9 KB

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