public static void Subscribe(IDisposable instance, Type interfaceCOM) { IntPtr pUnk = Marshal.GetComInterfaceForObject(instance, interfaceCOM); IntPtr vtable = Marshal.ReadIntPtr(pUnk); COMDisposable item = (COMDisposable)ITEMS[vtable]; if (item == null) { //gets the the Release function IntPtr releaseOriPtr = Marshal.ReadIntPtr(vtable, RELEASE_PTR_OFFSET); ReleaseDelegate releaseOri = (ReleaseDelegate)Marshal.GetDelegateForFunctionPointer( releaseOriPtr, typeof(ReleaseDelegate)); //saves the original function and reference count item = new COMDisposable(); item.ReleaseOri = releaseOri; item.RefCountStart = releaseOri(pUnk); ITEMS.Add(vtable, item); //overrides the Release function Marshal.WriteIntPtr(vtable, RELEASE_PTR_OFFSET, ReleaseNewPtr); } else { item.ReleaseOri(pUnk); } }
private static int Release(IntPtr pUnk) { IntPtr vtable = Marshal.ReadIntPtr(pUnk); COMDisposable item = (COMDisposable)ITEMS[vtable]; int refCount = item.ReleaseOri(pUnk); if (refCount < item.RefCountStart) { IDisposable obj = (IDisposable)Marshal.GetObjectForIUnknown(pUnk); item.ReleaseOri(pUnk); obj.Dispose(); } return(refCount); }