WeakReference.cpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "il2cpp-config.h"
  2. #include "gc/GCHandle.h"
  3. #include "utils/Memory.h"
  4. #include "vm/CCW.h"
  5. #include "vm/Exception.h"
  6. #include "vm/ScopedThreadAttacher.h"
  7. #include "WeakReference.h"
  8. #include "utils/New.h"
  9. il2cpp_hresult_t il2cpp::vm::WeakReference::Create(Il2CppObject* managedObject, Il2CppIWeakReference** result)
  10. {
  11. void* memory = utils::Memory::Malloc(sizeof(WeakReference));
  12. if (memory == NULL)
  13. return IL2CPP_E_OUTOFMEMORY;
  14. *result = new(memory) WeakReference(managedObject);
  15. return IL2CPP_S_OK;
  16. }
  17. il2cpp::vm::WeakReference::WeakReference(Il2CppObject* managedObject)
  18. {
  19. auto weakRef = gc::GCHandle::NewWeakref(managedObject, false);
  20. vm::Exception::RaiseIfError(weakRef.GetError());
  21. m_GCHandle = weakRef.Get();
  22. m_RefCount = 1;
  23. }
  24. il2cpp_hresult_t STDCALL il2cpp::vm::WeakReference::QueryInterface(const Il2CppGuid& iid, void** object)
  25. {
  26. if (memcmp(&iid, &Il2CppIUnknown::IID, sizeof(Il2CppGuid)) == 0 ||
  27. memcmp(&iid, &Il2CppIWeakReference::IID, sizeof(Il2CppGuid)) == 0)
  28. {
  29. AddRef();
  30. *object = static_cast<Il2CppIWeakReference*>(this);
  31. return IL2CPP_S_OK;
  32. }
  33. return IL2CPP_E_NOINTERFACE;
  34. }
  35. uint32_t STDCALL il2cpp::vm::WeakReference::AddRef()
  36. {
  37. return ++m_RefCount;
  38. }
  39. uint32_t STDCALL il2cpp::vm::WeakReference::Release()
  40. {
  41. const uint32_t refCount = --m_RefCount;
  42. if (refCount == 0)
  43. {
  44. this->~WeakReference();
  45. utils::Memory::Free(this);
  46. }
  47. return refCount;
  48. }
  49. il2cpp_hresult_t STDCALL il2cpp::vm::WeakReference::Resolve(const Il2CppGuid& iid, Il2CppIInspectable** object)
  50. {
  51. ScopedThreadAttacher managedThreadAttached;
  52. Il2CppObject* managedObject = gc::GCHandle::GetTarget(m_GCHandle);
  53. if (managedObject == NULL)
  54. {
  55. *object = NULL;
  56. return IL2CPP_S_OK;
  57. }
  58. try
  59. {
  60. *object = static_cast<Il2CppIInspectable*>(CCW::GetOrCreate(managedObject, iid));
  61. }
  62. catch (Il2CppExceptionWrapper& ex)
  63. {
  64. return ex.ex->hresult;
  65. }
  66. return IL2CPP_S_OK;
  67. }