Skip to content

Commit

Permalink
Make MarshalGeneric use ObjectReferenceValue. (#1132)
Browse files Browse the repository at this point in the history
  • Loading branch information
manodasanW authored Mar 12, 2022
1 parent d015a5f commit ba56eda
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 84 deletions.
36 changes: 26 additions & 10 deletions src/WinRT.Runtime/AgileReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,47 @@ class AgileReference : IDisposable
private readonly static Lazy<IGlobalInterfaceTable> Git = new Lazy<IGlobalInterfaceTable>(() => GetGitTable());
private readonly IObjectReference _agileReference;
private readonly IntPtr _cookie;
private bool disposed;

public unsafe AgileReference(IObjectReference instance)
private bool disposed;

public AgileReference(IObjectReference instance)
: this(instance?.ThisPtr ?? IntPtr.Zero)
{
}

internal AgileReference(in ObjectReferenceValue instance)
: this(instance.GetAbi())
{
}

internal unsafe AgileReference(IntPtr thisPtr)
{
if(instance?.ThisPtr == null)
if (thisPtr == IntPtr.Zero)
{
return;
}

}

IntPtr agileReference = default;
Guid iid = IUnknownVftbl.IID;
try
{
Marshal.ThrowExceptionForHR(Platform.RoGetAgileReference(
0 /*AGILEREFERENCE_DEFAULT*/,
ref iid,
instance.ThisPtr,
thisPtr,
&agileReference));
_agileReference = ObjectReference<IUnknownVftbl>.Attach(ref agileReference);
}
catch(TypeLoadException)
catch (TypeLoadException)
{
_cookie = Git.Value.RegisterInterfaceInGlobal(instance, iid);
_cookie = Git.Value.RegisterInterfaceInGlobal(thisPtr, iid);
}
finally
{
MarshalInterface<IAgileReference>.DisposeAbi(agileReference);
}
}


public IObjectReference Get() => _cookie == IntPtr.Zero ? ABI.WinRT.Interop.IAgileReferenceMethods.Resolve(_agileReference, IUnknownVftbl.IID) : Git.Value?.GetInterfaceFromGlobal(_cookie, IUnknownVftbl.IID);

internal ObjectReference<T> Get<T>(Guid iid) => _cookie == IntPtr.Zero ? ABI.WinRT.Interop.IAgileReferenceMethods.Resolve<T>(_agileReference, iid) : Git.Value?.GetInterfaceFromGlobal(_cookie, IUnknownVftbl.IID)?.As<T>(iid);
Expand Down Expand Up @@ -113,7 +124,12 @@ public void Dispose()
sealed class AgileReference<T> : AgileReference
where T : class
{
public unsafe AgileReference(IObjectReference instance)
public AgileReference(IObjectReference instance)
: base(instance)
{
}

internal AgileReference(in ObjectReferenceValue instance)
: base(instance)
{
}
Expand Down
4 changes: 4 additions & 0 deletions src/WinRT.Runtime/CastExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ public static AgileReference<T> AsAgile<T>(this T value) where T : class
{
return new AgileReference<T>(objref);
}
else if (marshal is ObjectReferenceValue objrefValue)
{
return new AgileReference<T>(objrefValue);
}
}
finally
{
Expand Down
6 changes: 3 additions & 3 deletions src/WinRT.Runtime/Interop/IAgileReference.net5.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface IAgileObject
[Guid("00000146-0000-0000-C000-000000000046")]
internal interface IGlobalInterfaceTable
{
IntPtr RegisterInterfaceInGlobal(IObjectReference objRef, Guid riid);
IntPtr RegisterInterfaceInGlobal(IntPtr ptr, Guid riid);
void RevokeInterfaceFromGlobal(IntPtr cookie);
IObjectReference GetInterfaceFromGlobal(IntPtr cookie, Guid riid);
}
Expand Down Expand Up @@ -161,9 +161,9 @@ public IGlobalInterfaceTable(ObjectReference<Vftbl> obj)
_obj = obj;
}

public IntPtr RegisterInterfaceInGlobal(IObjectReference objRef, Guid riid)
public IntPtr RegisterInterfaceInGlobal(IntPtr ptr, Guid riid)
{
ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.RegisterInterfaceInGlobal(ThisPtr, objRef.ThisPtr, ref riid, out IntPtr cookie));
ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.RegisterInterfaceInGlobal(ThisPtr, ptr, ref riid, out IntPtr cookie));
return cookie;

}
Expand Down
6 changes: 3 additions & 3 deletions src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ interface IAgileObject
[Guid("00000146-0000-0000-C000-000000000046")]
internal interface IGlobalInterfaceTable
{
IntPtr RegisterInterfaceInGlobal(IObjectReference objRef, Guid riid);
IntPtr RegisterInterfaceInGlobal(IntPtr ptr, Guid riid);
void RevokeInterfaceFromGlobal(IntPtr cookie);
IObjectReference GetInterfaceFromGlobal(IntPtr cookie, Guid riid);
}
Expand Down Expand Up @@ -225,9 +225,9 @@ public IGlobalInterfaceTable(ObjectReference<Vftbl> obj)
_obj = obj;
}

public IntPtr RegisterInterfaceInGlobal(IObjectReference objRef, Guid riid)
public IntPtr RegisterInterfaceInGlobal(IntPtr ptr, Guid riid)
{
ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.RegisterInterfaceInGlobal(ThisPtr, objRef.ThisPtr, ref riid, out IntPtr cookie));
ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.RegisterInterfaceInGlobal(ThisPtr, ptr, ref riid, out IntPtr cookie));
return cookie;

}
Expand Down
Loading

0 comments on commit ba56eda

Please sign in to comment.