Exemple #1
0
            protected unsafe override ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
            {
                Assert.IsTrue(obj is Test);

                IntPtr fpQueryInteface = default;
                IntPtr fpAddRef        = default;
                IntPtr fpRelease       = default;

                ComWrappers.GetIUnknownImpl(out fpQueryInteface, out fpAddRef, out fpRelease);

                var vtbl = new ITestVtbl()
                {
                    IUnknownImpl = new IUnknownVtbl()
                    {
                        QueryInterface = fpQueryInteface,
                        AddRef         = fpAddRef,
                        Release        = fpRelease
                    },
                    SetValue = Marshal.GetFunctionPointerForDelegate(ITestVtbl.pSetValue)
                };
                var vtblRaw = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ITestVtbl), sizeof(ITestVtbl));

                Marshal.StructureToPtr(vtbl, vtblRaw, false);

                var entryRaw = (ComInterfaceEntry *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ITestVtbl), sizeof(ComInterfaceEntry));

                entryRaw->IID    = typeof(ITest).GUID;
                entryRaw->Vtable = vtblRaw;

                count = 1;
                return(entryRaw);
            }
            private unsafe ComInterfaceEntry *ComputeVtablesForTestObject(Test obj, out int count)
            {
                IntPtr fpQueryInteface = default;
                IntPtr fpAddRef        = default;
                IntPtr fpRelease       = default;

                ComWrappers.GetIUnknownImpl(out fpQueryInteface, out fpAddRef, out fpRelease);

                var iUnknownVtbl = new IUnknownVtbl()
                {
                    QueryInterface = fpQueryInteface,
                    AddRef         = fpAddRef,
                    Release        = fpRelease
                };

                var vtbl = new ITestVtbl()
                {
                    IUnknownImpl = iUnknownVtbl,
                    SetValue     = Marshal.GetFunctionPointerForDelegate(ITestVtbl.pSetValue)
                };
                var vtblRaw = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ITestVtbl), sizeof(ITestVtbl));

                Marshal.StructureToPtr(vtbl, vtblRaw, false);

                int countLocal = obj is TestEx ? ((TestEx)obj).Interfaces.Length + 1 : 1;
                var entryRaw   = (ComInterfaceEntry *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ITestVtbl), sizeof(ComInterfaceEntry) * countLocal);

                entryRaw[0].IID    = typeof(ITest).GUID;
                entryRaw[0].Vtable = vtblRaw;

                if (obj is TestEx)
                {
                    var iUnknownVtblRaw = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IUnknownVtbl), sizeof(IUnknownVtbl));
                    Marshal.StructureToPtr(iUnknownVtbl, iUnknownVtblRaw, false);

                    var testEx = (TestEx)obj;
                    for (int i = 1; i < testEx.Interfaces.Length + 1; i++)
                    {
                        // Including interfaces to allow QI, but not actually returning a valid vtable, since it is not needed for the tests here.
                        entryRaw[i].IID    = testEx.Interfaces[i - 1];
                        entryRaw[i].Vtable = iUnknownVtblRaw;
                    }
                }

                count = countLocal;
                return(entryRaw);
            }