public override unsafe int TryAs <U>(Guid iid, out ObjectReference <U> objRef) { objRef = null; int hr = VftblIUnknown.QueryInterface(ThisPtr, ref iid, out IntPtr thatPtr); if (hr >= 0) { if (IsAggregated) { Marshal.Release(thatPtr); } AddRefFromTrackerSource(); using (var contextCallbackReference = ObjectReference <ABI.WinRT.Interop.IContextCallback.Vftbl> .FromAbi(_contextCallbackPtr)) { objRef = new ObjectReferenceWithContext <U>(thatPtr, contextCallbackReference.GetRef()) { IsAggregated = IsAggregated, PreventReleaseOnDispose = IsAggregated, ReferenceTrackerPtr = ReferenceTrackerPtr }; } } return(hr); }
// Calls the given callback in the right context. // On any exception, calls onFail callback if any set. // If not set, exception is handled due to today we don't // have any scenario to propagate it from here. public unsafe static void CallInContext(IntPtr contextCallbackPtr, IntPtr contextToken, Action callback, Action onFailCallback) { // Check if we are already on the same context, if so we do not need to switch. if (contextCallbackPtr == IntPtr.Zero || GetContextToken() == contextToken) { callback(); return; } ComCallData data = default; var contextCallback = new ABI.WinRT.Interop.IContextCallback(ObjectReference <ABI.WinRT.Interop.IContextCallback.Vftbl> .FromAbi(contextCallbackPtr)); try { contextCallback.ContextCallback(_ => { callback(); return(0); }, &data, IID_ICallbackWithNoReentrancyToApplicationSTA, 5); } catch (Exception) { onFailCallback?.Invoke(); } }
public override unsafe int TryAs <U>(Guid iid, out ObjectReference <U> objRef) { objRef = null; int hr = VftblIUnknown.QueryInterface(ThisPtr, ref iid, out IntPtr thatPtr); if (hr >= 0) { using (var contextCallbackReference = ObjectReference <ABI.WinRT.Interop.IContextCallback.Vftbl> .FromAbi(_contextCallbackPtr)) { objRef = new ObjectReferenceWithContext <U>(thatPtr, contextCallbackReference.GetRef()); } } return(hr); }
public static IObjectReference GetObjectReferenceForInterface(IntPtr externalComObject) { using var unknownRef = ObjectReference<IUnknownVftbl>.FromAbi(externalComObject); if (unknownRef.TryAs<IUnknownVftbl>(typeof(ABI.WinRT.Interop.IAgileObject.Vftbl).GUID, out var agileRef) >= 0) { agileRef.Dispose(); return unknownRef.As<IUnknownVftbl>(); } else { return new ObjectReferenceWithContext<IUnknownVftbl>( unknownRef.GetRef(), Context.GetContextCallback()); } }
public static IInspectable FromAbi(IntPtr thisPtr) => new IInspectable(ObjectReference <Vftbl> .FromAbi(thisPtr));