BsMonoUtil.h 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #pragma once
  2. #include "BsMonoPrerequisites.h"
  3. #include "CmException.h"
  4. #include "CmDebug.h"
  5. #include <mono/jit/jit.h>
  6. namespace BansheeEngine
  7. {
  8. class BS_MONO_EXPORT MonoUtil
  9. {
  10. public:
  11. static CM::WString monoToWString(MonoString* str)
  12. {
  13. if(str == nullptr)
  14. return CM::StringUtil::WBLANK;
  15. int len = mono_string_length(str);
  16. mono_unichar2* monoChars = mono_string_chars(str);
  17. CM::WString ret(len, '0');
  18. for(int i = 0; i < len; i++)
  19. ret[i] = monoChars[i];
  20. return ret;
  21. }
  22. static MonoString* wstringToMono(MonoDomain* domain, const CM::WString& str)
  23. {
  24. CM::UINT32 len = (CM::UINT32)str.length();
  25. mono_unichar2* monoChars = (mono_unichar2*)CM::cm_alloc<mono_unichar2>(len);
  26. for(CM::UINT32 i = 0; i < len; i++)
  27. monoChars[i] = str[i];
  28. MonoString* monoString = mono_string_new_utf16(domain, monoChars, len);
  29. CM::cm_free(monoChars);
  30. return monoString;
  31. }
  32. static void throwIfException(MonoException* exception)
  33. {
  34. throwIfException(reinterpret_cast<MonoObject*>(exception));
  35. }
  36. static void throwIfException(MonoObject* exception)
  37. {
  38. if(exception != nullptr)
  39. {
  40. ::MonoClass* exceptionClass = mono_object_get_class(exception);
  41. ::MonoProperty* exceptionMsgProp = mono_class_get_property_from_name(exceptionClass, "Message");
  42. ::MonoMethod* exceptionMsgGetter = mono_property_get_get_method(exceptionMsgProp);
  43. MonoString* exceptionMsg = (MonoString*)mono_runtime_invoke(exceptionMsgGetter, exception, nullptr, nullptr);
  44. ::MonoProperty* exceptionStackProp = mono_class_get_property_from_name(exceptionClass, "StackTrace");
  45. ::MonoMethod* exceptionStackGetter = mono_property_get_get_method(exceptionStackProp);
  46. MonoString* exceptionStackTrace = (MonoString*)mono_runtime_invoke(exceptionStackGetter, exception, nullptr, nullptr);
  47. CM::String msg = "Managed exception: " + toString(monoToWString(exceptionMsg)) + "\n" + toString(monoToWString(exceptionStackTrace));
  48. LOGERR(msg);
  49. CM_EXCEPT(CM::InternalErrorException, msg);
  50. }
  51. }
  52. };
  53. }