CCWBase.cpp 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include "il2cpp-config.h"
  2. #include "il2cpp-string-types.h"
  3. #include "CCWBase.h"
  4. #include "metadata/GenericMetadata.h"
  5. #include "os/WindowsRuntime.h"
  6. #include "vm/Class.h"
  7. #include "vm/GenericClass.h"
  8. #include "vm/MetadataCache.h"
  9. #include "vm/WeakReference.h"
  10. #include "utils/StringUtils.h"
  11. static inline const Il2CppClass* GetBoxedWindowsRuntimeClass(const Il2CppClass* typeDefinition, const Il2CppClass* genericArg)
  12. {
  13. const Il2CppType* klass = &genericArg->byval_arg;
  14. const Il2CppGenericInst* inst = il2cpp::vm::MetadataCache::GetGenericInst(&klass, 1);
  15. Il2CppGenericClass* genericClass = il2cpp::metadata::GenericMetadata::GetGenericClass(typeDefinition, inst);
  16. return il2cpp::vm::GenericClass::GetClass(genericClass);
  17. }
  18. static inline bool CanPotentiallyBeBoxedToWindowsRuntime(const Il2CppClass* klass)
  19. {
  20. if (il2cpp::vm::Class::IsInflated(klass))
  21. return false;
  22. if (il2cpp::vm::Class::IsValuetype(klass))
  23. return true;
  24. if (klass == il2cpp_defaults.string_class)
  25. return true;
  26. return false;
  27. }
  28. il2cpp_hresult_t il2cpp::vm::CCWBase::GetRuntimeClassNameImpl(Il2CppHString* className)
  29. {
  30. const Il2CppClass* objectClass = GetManagedObjectInline()->klass;
  31. if (il2cpp_defaults.ireference_class != NULL && CanPotentiallyBeBoxedToWindowsRuntime(objectClass))
  32. {
  33. // For value types/strings we're supposed to return the name of its boxed representation, i.e. Windows.Foundation.IReference`1<T>
  34. objectClass = GetBoxedWindowsRuntimeClass(il2cpp_defaults.ireference_class, objectClass);
  35. }
  36. else if (il2cpp_defaults.ireferencearray_class != NULL && objectClass->rank > 0)
  37. {
  38. // For arrays of value types/strings we're supposed to return the name of its boxed representation too, i.e. Windows.Foundation.IReferenceArray`1<T>
  39. const Il2CppClass* elementClass = objectClass->element_class;
  40. if (CanPotentiallyBeBoxedToWindowsRuntime(elementClass))
  41. {
  42. objectClass = GetBoxedWindowsRuntimeClass(il2cpp_defaults.ireferencearray_class, elementClass);
  43. }
  44. else if (elementClass == il2cpp_defaults.object_class || strcmp(elementClass->image->assembly->aname.name, "WindowsRuntimeMetadata") == 0)
  45. {
  46. // Object arrays can be boxed, but objects cannot, so we need to special case it
  47. // For object and WindowsRuntime classes arrays, we also return Windows.Foundation.IReferenceArray`1<Object>
  48. return os::WindowsRuntime::CreateHString(utils::StringView<Il2CppNativeChar>(IL2CPP_NATIVE_STRING("Windows.Foundation.IReferenceArray`1<Object>")), className);
  49. }
  50. }
  51. const char* name = MetadataCache::GetWindowsRuntimeClassName(objectClass);
  52. if (name == NULL)
  53. {
  54. *className = NULL;
  55. return IL2CPP_S_OK;
  56. }
  57. UTF16String nameUtf16 = utils::StringUtils::Utf8ToUtf16(name);
  58. return os::WindowsRuntime::CreateHString(utils::StringView<Il2CppChar>(nameUtf16.c_str(), nameUtf16.length()), className);
  59. }
  60. Il2CppObject* STDCALL il2cpp::vm::CCWBase::GetManagedObject()
  61. {
  62. return GetManagedObjectInline();
  63. }
  64. il2cpp_hresult_t STDCALL il2cpp::vm::CCWBase::GetWeakReference(Il2CppIWeakReference** weakReference)
  65. {
  66. return WeakReference::Create(GetManagedObjectInline(), weakReference);
  67. }