public COMCallableIUnknown() { _handle = GCHandle.Alloc(this); IUnknownVTable * vtable = (IUnknownVTable *)Marshal.AllocHGlobal(sizeof(IUnknownVTable)).ToPointer(); QueryInterfaceDelegate qi = new QueryInterfaceDelegate(QueryInterfaceImpl); vtable->QueryInterface = Marshal.GetFunctionPointerForDelegate(qi); _delegates.Add(qi); AddRefDelegate addRef = new AddRefDelegate(AddRefImpl); vtable->AddRef = Marshal.GetFunctionPointerForDelegate(addRef); _delegates.Add(addRef); ReleaseDelegate release = new ReleaseDelegate(ReleaseImpl); vtable->Release = Marshal.GetFunctionPointerForDelegate(release); _delegates.Add(release); IUnknownObject = Marshal.AllocHGlobal(IntPtr.Size); *(void **)IUnknownObject = vtable; _interfaces.Add(IUnknownGuid, IUnknownObject); }
/// <summary> /// Release an IUnknown pointer. /// </summary> /// <param name="pUnk">A pointer to the IUnknown interface to release.</param> /// <returns>The result of pUnk->Release().</returns> public static unsafe int Release(IntPtr pUnk) { if (pUnk == IntPtr.Zero) { return(0); } IUnknownVTable *vtable = *(IUnknownVTable **)pUnk; ReleaseDelegate release = (ReleaseDelegate)Marshal.GetDelegateForFunctionPointer(vtable->Release, typeof(ReleaseDelegate)); return(release(pUnk)); }
protected CallableCOMWrapper(CallableCOMWrapper toClone) { if (toClone._disposed) { throw new ObjectDisposedException(GetType().FullName); } Self = toClone.Self; _unknownVTable = toClone._unknownVTable; _library = toClone._library; AddRef(); _library.AddRef(); }
private protected CallableCOMWrapper(RefCountedFreeLibrary library, ref Guid desiredInterface, IntPtr pUnknown) { _library = library; _library.AddRef(); IUnknownVTable *tbl = *(IUnknownVTable **)pUnknown; var queryInterface = (QueryInterfaceDelegate)Marshal.GetDelegateForFunctionPointer(tbl->QueryInterface, typeof(QueryInterfaceDelegate)); int hr = queryInterface(pUnknown, ref desiredInterface, out IntPtr pCorrectUnknown); if (hr != 0) { GC.SuppressFinalize(this); throw new InvalidOperationException(); } var release = (ReleaseDelegate)Marshal.GetDelegateForFunctionPointer(tbl->Release, typeof(ReleaseDelegate)); int count = release(pUnknown); Self = pCorrectUnknown; _unknownVTable = *(IUnknownVTable **)pCorrectUnknown; }
internal CallableCOMWrapper(DacLibrary library, ref Guid desiredInterface, IntPtr pUnknown) { Interlocked.Increment(ref _totalInstances); IUnknownVTable *tbl = *(IUnknownVTable **)pUnknown; var queryInterface = (QueryInterfaceDelegate)Marshal.GetDelegateForFunctionPointer(tbl->QueryInterface, typeof(QueryInterfaceDelegate)); int hr = queryInterface(pUnknown, ref desiredInterface, out IntPtr pCorrectUnknown); if (hr != 0) { GC.SuppressFinalize(this); throw new InvalidOperationException(); } var release = (ReleaseDelegate)Marshal.GetDelegateForFunctionPointer(tbl->Release, typeof(ReleaseDelegate)); release(pUnknown); Self = pCorrectUnknown; _unknownVTable = *(IUnknownVTable **)pCorrectUnknown; _library = GCHandle.Alloc(library); }
protected CallableCOMWrapper(RefCountedFreeLibrary library, ref Guid desiredInterface, IntPtr pUnknown) { _library = library; _library.AddRef(); IUnknownVTable *tbl = *(IUnknownVTable **)pUnknown; QueryInterfaceDelegate queryInterface = (QueryInterfaceDelegate)Marshal.GetDelegateForFunctionPointer(tbl->QueryInterface, typeof(QueryInterfaceDelegate)); int hr = queryInterface(pUnknown, ref desiredInterface, out IntPtr pCorrectUnknown); if (hr != 0) { GC.SuppressFinalize(this); throw new InvalidCastException($"{GetType().FullName}.QueryInterface({desiredInterface}) failed, hr=0x{hr:x}"); } ReleaseDelegate release = (ReleaseDelegate)Marshal.GetDelegateForFunctionPointer(tbl->Release, typeof(ReleaseDelegate)); int count = release(pUnknown); Self = pCorrectUnknown; _unknownVTable = *(IUnknownVTable **)pCorrectUnknown; }