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); }