public ManagedObject(object managed, Guid iid, Delegate[] delegates)
        {
            this.managed = managed;
            this.iid     = iid;

            IntPtr[] nativeTable = new IntPtr[delegates.Length + 4];
            gchNativeData = GCHandle.Alloc(nativeTable, GCHandleType.Pinned);
            LiveObjectsCache.managedAdd(address, this);

            // A COM pointer is an address of address: "this" points to vtable pointer, vtable pointer points to the first vtable entry, the rest of the entries follow.
            // We want binary compatibility, so nativeTable[ 0 ] contains address of nativeTable[ 1 ], and methods function pointers start at nativeTable[ 1 ].
            nativeTable[0] = address + Marshal.SizeOf <IntPtr>();

            // Build 3 first entries of the vtable, with IUnknown methods
            queryInterface = delegate(IntPtr pThis, ref Guid ii, out IntPtr result) { Debug.Assert(pThis == address); return(implQueryInterface(ref ii, out result)); };
            nativeTable[1] = Marshal.GetFunctionPointerForDelegate(queryInterface);

            addRef         = delegate(IntPtr pThis) { Debug.Assert(pThis == address); return(implAddRef()); };
            nativeTable[2] = Marshal.GetFunctionPointerForDelegate(addRef);

            release        = delegate(IntPtr pThis) { Debug.Assert(pThis == address); return(implRelease()); };
            nativeTable[3] = Marshal.GetFunctionPointerForDelegate(release);

            // Custom methods entries of the vtable
            for (int i = 0; i < delegates.Length; i++)
            {
                nativeTable[i + 4] = Marshal.GetFunctionPointerForDelegate(delegates[i]);
            }
            ;
        }
Exemple #2
0
 /// <summary>Construct the wrapper.</summary>
 public RuntimeClass(IntPtr ptr, IntPtr[] vtbl, Guid iid)
 {
     m_nativePointer = ptr;
     this.iid        = iid;
     QueryInterface  = Marshal.GetDelegateForFunctionPointer <IUnknown.QueryInterface>(vtbl[0]);
     AddRef          = Marshal.GetDelegateForFunctionPointer <IUnknown.AddRef>(vtbl[1]);
     Release         = Marshal.GetDelegateForFunctionPointer <IUnknown.Release>(vtbl[2]);
     Cache.Native.add(ptr, this);
 }