public NativeObject(string name, IntPtr obj, Dictionary <RuntimeTypeHandle, RuntimeTypeHandle> interfaceMap) { Name = name; _objPtr = obj; _interfaceTypeToImplType = interfaceMap; VtblPtr vtblPtr = Marshal.PtrToStructure <VtblPtr>(obj); _unknownVtbl = Marshal.PtrToStructure <IUnknownVtbl>(vtblPtr.Vtbl); }
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); }
protected unsafe override ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { LastComputeVtablesObject = obj; if (ReturnInvalid) { count = -1; return(null); } if (obj is Test) { return(ComputeVtablesForTestObject((Test)obj, out count)); } else if (string.Equals(ManagedServerTypeName, obj.GetType().Name)) { IntPtr fpQueryInteface = default; IntPtr fpAddRef = default; IntPtr fpRelease = default; ComWrappers.GetIUnknownImpl(out fpQueryInteface, out fpAddRef, out fpRelease); var vtbl = new IUnknownVtbl() { QueryInterface = fpQueryInteface, AddRef = fpAddRef, Release = fpRelease }; var vtblRaw = RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IUnknownVtbl), sizeof(IUnknownVtbl)); Marshal.StructureToPtr(vtbl, vtblRaw, false); // Including interfaces to allow QI, but not actually returning a valid vtable, since it is not needed for the tests here. var entryRaw = (ComInterfaceEntry *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IUnknownVtbl), sizeof(ComInterfaceEntry)); entryRaw[0].IID = typeof(Server.Contract.IConsumeNETServer).GUID; entryRaw[0].Vtable = vtblRaw; count = 1; return(entryRaw); } count = -1; return(null); }