| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "BsMonoUtil.h"
- #include "Debug/BsDebug.h"
- #include <mono/jit/jit.h>
- namespace bs
- {
- WString MonoUtil::monoToWString(MonoString* str)
- {
- if (str == nullptr)
- return StringUtil::WBLANK;
- int len = mono_string_length(str);
- mono_unichar2* monoChars = mono_string_chars(str);
- WString ret(len, '0');
- for (int i = 0; i < len; i++)
- ret[i] = monoChars[i];
- return ret;
- }
- String MonoUtil::monoToString(MonoString* str)
- {
- if (str == nullptr)
- return StringUtil::BLANK;
- int len = mono_string_length(str);
- mono_unichar2* monoChars = mono_string_chars(str);
- String ret(len, '0');
- for (int i = 0; i < len; i++)
- ret[i] = (char)monoChars[i];
- return ret;
- }
- MonoString* MonoUtil::wstringToMono(const WString& str)
- {
- if (sizeof(wchar_t) == 2) // Assuming UTF-16
- return mono_string_from_utf16((mono_unichar2*)str.c_str());
- else // Assuming UTF-32
- return mono_string_from_utf32((mono_unichar4*)str.c_str());
- }
- MonoString* MonoUtil::stringToMono(const String& str)
- {
- return wstringToMono(toWString(str));
- }
- void MonoUtil::getClassName(MonoObject* obj, String& ns, String& typeName)
- {
- if (obj == nullptr)
- return;
- ::MonoClass* monoClass = mono_object_get_class(obj);
- getClassName(monoClass, ns, typeName);
- }
- void MonoUtil::getClassName(::MonoClass* monoClass, String& ns, String& typeName)
- {
- ::MonoClass* nestingClass = mono_class_get_nesting_type(monoClass);
- if (nestingClass == nullptr)
- {
- ns = mono_class_get_namespace(monoClass);
- typeName = mono_class_get_name(monoClass);
- return;
- }
- else
- {
- typeName = String("+") + mono_class_get_name(monoClass);
- do
- {
- ::MonoClass* nextNestingClass = mono_class_get_nesting_type(nestingClass);
- if (nextNestingClass != nullptr)
- {
- typeName = String("+") + mono_class_get_name(nestingClass) + typeName;
- nestingClass = nextNestingClass;
- }
- else
- {
- ns = mono_class_get_namespace(nestingClass);
- typeName = mono_class_get_name(nestingClass) + typeName;
- break;
- }
- } while (true);
- }
- }
- void MonoUtil::getClassName(MonoReflectionType* monoReflType, String& ns, String& typeName)
- {
- MonoType* monoType = mono_reflection_type_get_type(monoReflType);
- ::MonoClass* monoClass = mono_type_get_class(monoType);
- getClassName(monoClass, ns, typeName);
- }
- ::MonoClass* MonoUtil::getClass(MonoObject* object)
- {
- return mono_object_get_class(object);
- }
- ::MonoClass* MonoUtil::getClass(MonoReflectionType* type)
- {
- MonoType* monoType = mono_reflection_type_get_type(type);
- return mono_type_get_class(monoType);
- }
- MonoReflectionType* MonoUtil::getType(MonoObject* object)
- {
- ::MonoClass* klass = getClass(object);
- return getType(klass);
- }
- MonoReflectionType* MonoUtil::getType(::MonoClass* klass)
- {
- MonoType* monoType = mono_class_get_type(klass);
- return mono_type_get_object(MonoManager::instance().getDomain(), monoType);
- }
- UINT32 MonoUtil::newGCHandle(MonoObject* object, bool pinned)
- {
- return mono_gchandle_new(object, pinned);
- }
- UINT32 MonoUtil::newWeakGCHandle(MonoObject* object)
- {
- return mono_gchandle_new_weakref(object, false);
- }
- void MonoUtil::freeGCHandle(UINT32 handle)
- {
- mono_gchandle_free(handle);
- }
- MonoObject* MonoUtil::getObjectFromGCHandle(UINT32 handle)
- {
- return mono_gchandle_get_target(handle);
- }
- MonoObject* MonoUtil::box(::MonoClass* klass, void* value)
- {
- return mono_value_box(MonoManager::instance().getDomain(), klass, value);
- }
- void* MonoUtil::unbox(MonoObject* object)
- {
- return mono_object_unbox(object);
- }
- bool MonoUtil::isSubClassOf(::MonoClass* subClass, ::MonoClass* parentClass)
- {
- return mono_class_is_subclass_of(subClass, parentClass, true) != 0;
- }
- bool MonoUtil::isValueType(::MonoClass* klass)
- {
- return mono_class_is_valuetype(klass) != 0;
- }
- bool MonoUtil::isEnum(::MonoClass* object)
- {
- return mono_class_is_enum(object) != 0;
- }
- MonoPrimitiveType MonoUtil::getEnumPrimitiveType(::MonoClass* enumClass)
- {
- MonoType* monoType = mono_class_get_type(enumClass);
- MonoType* underlyingType = mono_type_get_underlying_type(monoType);
- return getPrimitiveType(mono_type_get_class(underlyingType));
- }
- MonoPrimitiveType MonoUtil::getPrimitiveType(::MonoClass* monoClass)
- {
- MonoType* monoType = mono_class_get_type(monoClass);
- int monoPrimitiveType = mono_type_get_type(monoType);
- switch(monoPrimitiveType)
- {
- case MONO_TYPE_BOOLEAN:
- return MonoPrimitiveType::Boolean;
- case MONO_TYPE_CHAR:
- return MonoPrimitiveType::Char;
- case MONO_TYPE_I1:
- return MonoPrimitiveType::I8;
- case MONO_TYPE_U1:
- return MonoPrimitiveType::U8;
- case MONO_TYPE_I2:
- return MonoPrimitiveType::I16;
- case MONO_TYPE_U2:
- return MonoPrimitiveType::U16;
- case MONO_TYPE_I4:
- return MonoPrimitiveType::I32;
- case MONO_TYPE_U4:
- return MonoPrimitiveType::U32;
- case MONO_TYPE_I8:
- return MonoPrimitiveType::I64;
- case MONO_TYPE_U8:
- return MonoPrimitiveType::U64;
- case MONO_TYPE_R4:
- return MonoPrimitiveType::R32;
- case MONO_TYPE_R8:
- return MonoPrimitiveType::R64;
- case MONO_TYPE_STRING:
- return MonoPrimitiveType::String;
- case MONO_TYPE_CLASS:
- return MonoPrimitiveType::Class;
- case MONO_TYPE_VALUETYPE:
- return MonoPrimitiveType::ValueType;
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- return MonoPrimitiveType::Array;
- case MONO_TYPE_GENERICINST:
- return MonoPrimitiveType::Generic;
- default:
- break;
- }
- return MonoPrimitiveType::Unknown;
- }
- ::MonoClass* MonoUtil::bindGenericParameters(::MonoClass* klass, ::MonoClass** params, UINT32 numParams)
- {
- MonoType** types = (MonoType**)bs_alloc(sizeof(MonoType*) * numParams);
- for (UINT32 i = 0; i < numParams; i++)
- types[i] = mono_class_get_type(params[i]);
- return mono_class_bind_generic_parameters(klass, numParams, types, false);
- }
- ::MonoClass* MonoUtil::getUINT16Class()
- {
- return mono_get_uint16_class();
- }
- ::MonoClass* MonoUtil::getINT16Class()
- {
- return mono_get_int16_class();
- }
- ::MonoClass* MonoUtil::getUINT32Class()
- {
- return mono_get_uint32_class();
- }
- ::MonoClass* MonoUtil::getINT32Class()
- {
- return mono_get_int32_class();
- }
- ::MonoClass* MonoUtil::getUINT64Class()
- {
- return mono_get_uint64_class();
- }
- ::MonoClass* MonoUtil::getINT64Class()
- {
- return mono_get_int64_class();
- }
- ::MonoClass* MonoUtil::getStringClass()
- {
- return mono_get_string_class();
- }
- ::MonoClass* MonoUtil::getFloatClass()
- {
- return mono_get_single_class();
- }
- ::MonoClass* MonoUtil::getDoubleClass()
- {
- return mono_get_double_class();
- }
- ::MonoClass* MonoUtil::getBoolClass()
- {
- return mono_get_boolean_class();
- }
- ::MonoClass* MonoUtil::getByteClass()
- {
- return mono_get_byte_class();
- }
- ::MonoClass* MonoUtil::getSByteClass()
- {
- return mono_get_sbyte_class();
- }
- ::MonoClass* MonoUtil::getCharClass()
- {
- return mono_get_char_class();
- }
- ::MonoClass* MonoUtil::getObjectClass()
- {
- return mono_get_object_class();
- }
- void MonoUtil::throwIfException(MonoException* exception)
- {
- throwIfException(reinterpret_cast<MonoObject*>(exception));
- }
- void MonoUtil::throwIfException(MonoObject* exception)
- {
- if (exception != nullptr)
- {
- ::MonoClass* exceptionClass = mono_object_get_class(exception);
- ::MonoProperty* exceptionMsgProp = mono_class_get_property_from_name(exceptionClass, "Message");
- ::MonoMethod* exceptionMsgGetter = mono_property_get_get_method(exceptionMsgProp);
- MonoString* exceptionMsg = (MonoString*)mono_runtime_invoke(exceptionMsgGetter, exception, nullptr, nullptr);
- ::MonoProperty* exceptionStackProp = mono_class_get_property_from_name(exceptionClass, "StackTrace");
- ::MonoMethod* exceptionStackGetter = mono_property_get_get_method(exceptionStackProp);
- MonoString* exceptionStackTrace = (MonoString*)mono_runtime_invoke(exceptionStackGetter, exception, nullptr, nullptr);
- // Note: If you modify this format make sure to also modify Debug.ParseExceptionMessage in managed code.
- String msg = "Managed exception: " + toString(monoToWString(exceptionMsg)) + "\n" + toString(monoToWString(exceptionStackTrace));
- LOGERR(msg);
- }
- }
- }
|