BsMonoUtil.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #pragma once
  2. #include "BsMonoPrerequisites.h"
  3. #include "BsException.h"
  4. #include "BsDebug.h"
  5. #include <mono/jit/jit.h>
  6. namespace BansheeEngine
  7. {
  8. /**
  9. * @brief Utility class containing methods for various common Mono/Script related
  10. * operations.
  11. */
  12. class BS_MONO_EXPORT MonoUtil
  13. {
  14. public:
  15. /**
  16. * @brief Converts a Mono (i.e. managed) string to a native wide string.
  17. */
  18. static WString monoToWString(MonoString* str)
  19. {
  20. if(str == nullptr)
  21. return StringUtil::WBLANK;
  22. int len = mono_string_length(str);
  23. mono_unichar2* monoChars = mono_string_chars(str);
  24. WString ret(len, '0');
  25. for(int i = 0; i < len; i++)
  26. ret[i] = monoChars[i];
  27. return ret;
  28. }
  29. /**
  30. * @brief Converts a Mono (i.e. managed) string to a native narrow string.
  31. */
  32. static String monoToString(MonoString* str)
  33. {
  34. if(str == nullptr)
  35. return StringUtil::BLANK;
  36. int len = mono_string_length(str);
  37. mono_unichar2* monoChars = mono_string_chars(str);
  38. String ret(len, '0');
  39. for(int i = 0; i < len; i++)
  40. ret[i] = (char)monoChars[i];
  41. return ret;
  42. }
  43. /**
  44. * @brief Converts a native wide string to a Mono (i.e. managed) string.
  45. */
  46. static MonoString* wstringToMono(MonoDomain* domain, const WString& str)
  47. {
  48. return mono_string_from_utf16((mono_unichar2*)str.c_str());
  49. }
  50. /**
  51. * @brief Converts a native narrow string to a Mono (i.e. managed) string.
  52. */
  53. static MonoString* stringToMono(MonoDomain* domain, const String& str)
  54. {
  55. return wstringToMono(domain, toWString(str));
  56. }
  57. /**
  58. * @copydoc throwIfException
  59. */
  60. static void throwIfException(MonoException* exception)
  61. {
  62. throwIfException(reinterpret_cast<MonoObject*>(exception));
  63. }
  64. /**
  65. * @brief Throws a native exception if the provided object is a valid managed exception.
  66. */
  67. static void throwIfException(MonoObject* exception)
  68. {
  69. if(exception != nullptr)
  70. {
  71. ::MonoClass* exceptionClass = mono_object_get_class(exception);
  72. ::MonoProperty* exceptionMsgProp = mono_class_get_property_from_name(exceptionClass, "Message");
  73. ::MonoMethod* exceptionMsgGetter = mono_property_get_get_method(exceptionMsgProp);
  74. MonoString* exceptionMsg = (MonoString*)mono_runtime_invoke(exceptionMsgGetter, exception, nullptr, nullptr);
  75. ::MonoProperty* exceptionStackProp = mono_class_get_property_from_name(exceptionClass, "StackTrace");
  76. ::MonoMethod* exceptionStackGetter = mono_property_get_get_method(exceptionStackProp);
  77. MonoString* exceptionStackTrace = (MonoString*)mono_runtime_invoke(exceptionStackGetter, exception, nullptr, nullptr);
  78. String msg = "Managed exception: " + toString(monoToWString(exceptionMsg)) + "\n" + toString(monoToWString(exceptionStackTrace));
  79. LOGERR(msg);
  80. BS_EXCEPT(InternalErrorException, msg);
  81. }
  82. }
  83. };
  84. }