// Called by the runtime to execute the abstract instance function internal static unsafe void *CallComputeVtables( ComWrappersScenario scenario, ComWrappers?comWrappersImpl, object obj, CreateComInterfaceFlags flags, out int count ) { ComWrappers?impl = null; switch (scenario) { case ComWrappersScenario.Instance: impl = comWrappersImpl; break; case ComWrappersScenario.TrackerSupportGlobalInstance: impl = s_globalInstanceForTrackerSupport; break; case ComWrappersScenario.MarshallingGlobalInstance: impl = s_globalInstanceForMarshalling; break; } if (impl is null) { count = -1; return(null); } return(impl.ComputeVtables(obj, flags, out count)); }
protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { var entries = ComWrappersSupport.GetInterfaceTableEntries(obj); if (flags.HasFlag(CreateComInterfaceFlags.CallerDefinedIUnknown)) { entries.Add(new ComInterfaceEntry { IID = typeof(IUnknownVftbl).GUID, Vtable = IUnknownVftbl.AbiToProjectionVftblPtr }); } entries.Add(new ComInterfaceEntry { IID = typeof(IInspectable).GUID, Vtable = IInspectable.Vftbl.AbiToProjectionVftablePtr }); count = entries.Count; ComInterfaceEntry *nativeEntries = (ComInterfaceEntry *)Marshal.AllocCoTaskMem(sizeof(ComInterfaceEntry) * count); for (int i = 0; i < count; i++) { nativeEntries[i] = entries[i]; } ComInterfaceEntryCleanupTable.Add(obj, new VtableEntriesCleanupScout(nativeEntries)); return(nativeEntries); }
private static extern bool TryGetOrCreateComInterfaceForObjectInternal( ObjectHandleOnStack comWrappersImpl, long wrapperId, ObjectHandleOnStack instance, CreateComInterfaceFlags flags, out IntPtr retValue );
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); }
protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { // count = 0; // return null; count = 1; return(wrapperEntry); }
protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { Debug.Assert(obj is IDispatch); Debug.Assert(wrapperEntry != null); // Always return the same table mappings. count = 1; return(wrapperEntry); }
protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { Debug.Assert(obj is Interop.Ole32.IStream); Debug.Assert(s_wrapperEntry is not null); // Always return the same table mappings. count = 1; return(s_wrapperEntry); }
protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { Debug.Assert(obj is IDispatch); Debug.Assert(wrapperEntry != null); // Always return the same table mappings. // If the object supports more than the IDispatch interface that should be returned here. count = 1; return(wrapperEntry); }
/// <summary> /// Create a COM representation of the supplied object that can be passed to a non-managed environment. /// </summary> /// <param name="instance">The managed object to expose outside the .NET runtime.</param> /// <param name="flags">Flags used to configure the generated interface.</param> /// <returns>The generated COM interface that can be passed outside the .NET runtime.</returns> public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags) { if (instance == null) { throw new ArgumentNullException(nameof(instance)); } ComWrappers impl = this; return(GetOrCreateComInterfaceForObjectInternal(ObjectHandleOnStack.Create(ref impl), ObjectHandleOnStack.Create(ref instance), flags)); }
/// <summary> /// Create a COM representation of the supplied object that can be passed to a non-managed environment. /// </summary> /// <param name="instance">The managed object to expose outside the .NET runtime.</param> /// <param name="flags">Flags used to configure the generated interface.</param> /// <returns>The generated COM interface that can be passed outside the .NET runtime.</returns> public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags) { IntPtr ptr; if (!TryGetOrCreateComInterfaceForObjectInternal(this, instance, flags, out ptr)) { throw new ArgumentException(); } return(ptr); }
protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { if (obj is Interop.Ole32.IStream) { count = 1; return(s_streamEntry); } if (obj is Interop.Shell32.IFileDialogEvents) { count = 1; return(s_fileDialogEventsEntry); } if (obj is Ole32.IDropSource) { count = 1; return(s_dropSourceEntry); } if (obj is Interop.Ole32.IDropTarget) { count = 1; return(s_dropTargetEntry); } if (obj is IEnumString) { count = 1; return(s_enumStringEntry); } if (obj is IEnumFORMATETC) { count = 1; return(s_enumFormatEtcEntry); } if (obj is IDataObject) { count = 1; return(s_dataObjectEntry); } throw new NotImplementedException($"ComWrappers for type {obj.GetType()} not implemented."); }
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); }
/// <summary> /// Create a COM representation of the supplied object that can be passed to a non-managed environment. /// </summary> /// <param name="impl">The <see cref="ComWrappers" /> implementation to use when creating the COM representation.</param> /// <param name="instance">The managed object to expose outside the .NET runtime.</param> /// <param name="flags">Flags used to configure the generated interface.</param> /// <param name="retValue">The generated COM interface that can be passed outside the .NET runtime or IntPtr.Zero if it could not be created.</param> /// <returns>Returns <c>true</c> if a COM representation could be created, <c>false</c> otherwise</returns> /// <remarks> /// If <paramref name="impl" /> is <c>null</c>, the global instance (if registered) will be used. /// </remarks> private static bool TryGetOrCreateComInterfaceForObjectInternal( ComWrappers impl, object instance, CreateComInterfaceFlags flags, out IntPtr retValue ) { if (instance == null) { throw new ArgumentNullException(nameof(instance)); } return(TryGetOrCreateComInterfaceForObjectInternal( ObjectHandleOnStack.Create(ref impl), impl.id, ObjectHandleOnStack.Create(ref instance), flags, out retValue )); }
protected unsafe override ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { switch (ComputeVtablesMode) { case FailureMode.ReturnInvalid: { count = -1; return(null); } case FailureMode.ThrowException: throw new Exception() { HResult = ExceptionErrorCode }; default: Assert.Fail("Invalid failure mode"); throw new Exception("UNREACHABLE"); } }
protected unsafe override ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { Assert.Equal(CreateComInterfaceFlags.None, flags); IntPtr fpQueryInterface = default; IntPtr fpAddRef = default; IntPtr fpRelease = default; ComWrappers.GetIUnknownImpl(out fpQueryInterface, out fpAddRef, out fpRelease); var vtblRaw = (IntPtr *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ComWrappersImpl), IntPtr.Size * 3); vtblRaw[0] = fpQueryInterface; vtblRaw[1] = fpAddRef; vtblRaw[2] = fpRelease; var entryRaw = (ComInterfaceEntry *)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ComWrappersImpl), sizeof(ComInterfaceEntry)); entryRaw->IID = new Guid(IID_TestQueryInterface); entryRaw->Vtable = (IntPtr)vtblRaw; count = 1; return(entryRaw); }
protected abstract unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count);
public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags) { throw new PlatformNotSupportedException(); }
protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { // passing the managed object to COM is not currently supported throw new NotImplementedException(); }
// Call to execute the abstract instance function internal static unsafe void *CallComputeVtables(ComWrappers?comWrappersImpl, object obj, CreateComInterfaceFlags flags, out int count) { ComWrappers?impl = comWrappersImpl ?? s_globalInstance; if (impl is null) { count = -1; return(null); } return(impl.ComputeVtables(obj, flags, out count)); }
protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { throw new NotImplementedException(); }
protected override unsafe ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { // Always return the same table mappings. count = 1; return(wrapperEntry); }
protected unsafe override ComInterfaceEntry *ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) { count = 0; return(null); }
// Call to execute the abstract instance function internal static unsafe void *CallComputeVtables(ComWrappers?comWrappersImpl, object obj, CreateComInterfaceFlags flags, out int count) => (comWrappersImpl ?? s_globalInstance !).ComputeVtables(obj, flags, out count);
private static extern IntPtr GetOrCreateComInterfaceForObjectInternal(ObjectHandleOnStack comWrappersImpl, ObjectHandleOnStack instance, CreateComInterfaceFlags flags);