CCWBase.cpp 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. #if IL2CPP_TRIM_COM
  31. * className = NULL;
  32. return IL2CPP_S_OK;
  33. #else
  34. const Il2CppClass* objectClass = GetManagedObjectInline()->klass;
  35. if (il2cpp_defaults.ireference_class != NULL && CanPotentiallyBeBoxedToWindowsRuntime(objectClass))
  36. {
  37. // For value types/strings we're supposed to return the name of its boxed representation, i.e. Windows.Foundation.IReference`1<T>
  38. objectClass = GetBoxedWindowsRuntimeClass(il2cpp_defaults.ireference_class, objectClass);
  39. }
  40. else if (il2cpp_defaults.ireferencearray_class != NULL && objectClass->rank > 0)
  41. {
  42. // 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>
  43. const Il2CppClass* elementClass = objectClass->element_class;
  44. if (CanPotentiallyBeBoxedToWindowsRuntime(elementClass))
  45. {
  46. objectClass = GetBoxedWindowsRuntimeClass(il2cpp_defaults.ireferencearray_class, elementClass);
  47. }
  48. else if (elementClass == il2cpp_defaults.object_class || strcmp(elementClass->image->assembly->aname.name, "WindowsRuntimeMetadata") == 0)
  49. {
  50. // Object arrays can be boxed, but objects cannot, so we need to special case it
  51. // For object and WindowsRuntime classes arrays, we also return Windows.Foundation.IReferenceArray`1<Object>
  52. return os::WindowsRuntime::CreateHString(utils::StringView<Il2CppNativeChar>(IL2CPP_NATIVE_STRING("Windows.Foundation.IReferenceArray`1<Object>")), className);
  53. }
  54. }
  55. const char* name = MetadataCache::GetWindowsRuntimeClassName(objectClass);
  56. if (name == NULL)
  57. {
  58. *className = NULL;
  59. return IL2CPP_S_OK;
  60. }
  61. UTF16String nameUtf16 = utils::StringUtils::Utf8ToUtf16(name);
  62. return os::WindowsRuntime::CreateHString(utils::StringView<Il2CppChar>(nameUtf16.c_str(), nameUtf16.length()), className);
  63. #endif
  64. }
  65. Il2CppObject* STDCALL il2cpp::vm::CCWBase::GetManagedObject()
  66. {
  67. return GetManagedObjectInline();
  68. }
  69. il2cpp_hresult_t STDCALL il2cpp::vm::CCWBase::GetWeakReference(Il2CppIWeakReference** weakReference)
  70. {
  71. return WeakReference::Create(GetManagedObjectInline(), weakReference);
  72. }