-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
In the design doc for the COM source generator, we determined that we wanted to add a new attribute named System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute (name subject to change in API review) with the following tentative shape:
namespace System.Runtime.InteropServices.Marshalling;
[AttributeUsage(AttributeTargets.Interface)]
public class GeneratedComInterfaceAttribute
{
public GeneratedComInterfaceAttribute(Type comWrappersType);
public GeneratedComInterfaceAttribute(Type comWrappersType, bool generateManagedObjectWrapper, bool generateComObjectWrapper);
public Type ComWrappersType { get; };
public bool GenerateManagedObjectWrapper { get; } = true;
public bool GenerateComObjectWrapper { get; } = true;
public bool ExportInterfaceDefinition { get; }
}This attribute could also alternatively be a generic attribute so we as the source-generator authors don't need to handle validating the type passed to the constructor.
After discussing the design further, we also proposed adding a new public type that implements basic COM support around IUnknown as well as a ComWrappers-derived base class and an interface to help, possibly with the following shapes:
namespace System.Runtime.InteropServices.Marshalling;
// This type represents the TypeKey concept. We wrap the Guid type here mainly to signify specific usage (effectively make a strong typedef)
public readonly record struct InterfaceId(Guid IID);
public class ComObject : IDynamicInterfaceCastable, IUnmanagedVirtualMethodTableProvider<InterfaceId>
{
// Implement support for casting through IUnknown.
// No thread-affinity aware support.
// No IDispatch support.
// No aggregation support.
}
public abstract class GeneratedComWrappersBase<TComObject> : ComWrappers
{
}The user will use the attribute as follows:
[GeneratedComInterface(typeof(MyComWrappers))]
interface IFoo
{
void Bar();
}
public partial class MyComWrappers : GeneratedComWrappersBase<ComObject>
{
}This issues tracks the following components of the generator, each of which can be completed relatively independently:
- Implement the
ComputeVtablesmethod forMyComWrappersto return vtables for all interfaces with the[GeneratedComInterface]attribute that point atMyComWrappersthat the provided object implements. - Implement the
CreateObjectmethod to create an object of typeComObjectaround the provided external COM object.- Possibly generate a nested type that has optimized support for the provided interfaces (such as a cache where the expected interfaces have optimized access).
- Generate an
DynamicInterfaceCastableImplementation-interface for the marked interface that provides the managed-to-unmanaged implementation based on the design and generator in Introduce a source generator for invoking methods on unmanaged vtables #68276. - Generate a native vtable for the interface that implements the unmanaged-to-managed implemenation for when managed objects are passed to unmanaged code through the
ComWrapperstype.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status