RCW.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #pragma once
  2. #include "il2cpp-config.h"
  3. #include "il2cpp-object-internals.h"
  4. struct Il2CppComObject;
  5. struct Il2CppGuid;
  6. struct Il2CppIUnknown;
  7. namespace il2cpp
  8. {
  9. namespace vm
  10. {
  11. class LIBIL2CPP_CODEGEN_API RCW
  12. {
  13. public:
  14. static void Register(Il2CppComObject* rcw);
  15. static Il2CppObject* GetOrCreateFromIUnknown(Il2CppIUnknown* unknown, Il2CppClass* fallbackClass);
  16. static Il2CppObject* GetOrCreateFromIInspectable(Il2CppIInspectable* inspectable, Il2CppClass* fallbackClass);
  17. static Il2CppObject* GetOrCreateForSealedClass(Il2CppIUnknown* unknown, Il2CppClass* objectClass);
  18. static void Cleanup(Il2CppComObject* rcw);
  19. static bool CacheQueriedInterface(Il2CppComObject* rcw, const Il2CppGuid& iid, Il2CppIUnknown* queriedInterface);
  20. static const VirtualInvokeData* GetComInterfaceInvokeData(Il2CppComObject* rcw, const Il2CppClass* targetInterface, Il2CppMethodSlot slot);
  21. template<bool throwOnError>
  22. inline static Il2CppIUnknown* QueryInterfaceNoAddRef(Il2CppComObject* rcw, const Il2CppGuid& iid)
  23. {
  24. IL2CPP_ASSERT(rcw);
  25. IL2CPP_ASSERT(rcw->identity);
  26. Il2CppIUnknown* result = QueryInterfaceCached(rcw, iid);
  27. if (result != NULL)
  28. return result;
  29. const il2cpp_hresult_t hr = rcw->identity->QueryInterface(iid, reinterpret_cast<void**>(&result));
  30. if (IL2CPP_HR_FAILED(hr))
  31. {
  32. if (throwOnError)
  33. Exception::Raise(hr, true);
  34. return NULL;
  35. }
  36. IL2CPP_ASSERT(result);
  37. if (!CacheQueriedInterface(rcw, iid, result))
  38. {
  39. // We lost the race - another thread won it.
  40. result->Release();
  41. return QueryInterfaceCached(rcw, iid);
  42. }
  43. return result;
  44. }
  45. private:
  46. static Il2CppIUnknown* QueryInterfaceCached(Il2CppComObject* rcw, const Il2CppGuid& iid);
  47. static const VirtualInvokeData* GetComInterfaceInvokeData(Il2CppClass* queriedInterface, const Il2CppClass* targetInterface, Il2CppMethodSlot slot);
  48. };
  49. } /* namespace vm */
  50. } /* namespace il2cpp */