Background and motivation
It would be nice to have some wrappers that would return other interfaces pointers, something like:
ComWrappers.TryGetComInstance<T>(unwrapped, out nint iface);
that would do the QI so I could call it like this:
ComWrappers.TryGetComInstance<IFoo>(unwrapped, out nint ifoo);
As a "frequent COM flyer", It's quite perturbing to have to juggle between ComWrappers and Marshal classes, actually it would be nice with all that new code to be able to avoid using Marshal completely :-)
Originally posted by @smourier in #106978 (comment)
public abstract partial class ComWrappers
{
+ public bool TryGetComInstance<TInterface>(object instance, CreateComInterfaceFlags flags, out IntPtr result);
}
This could also be an auto-generated method that would be provided on a derived ComWrappers instance. Looking up the IID on TInterface would need to be AOT friendly, which means typeof(TInterface).GUID is out.
API Proposal
The below API is modified from the OP proposal to align with existing API shape and motivating example below.
public abstract class ComWrappers
{
public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags);
+ public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags, in Guid interfaceId);
}
public class StrategyBasedComWrappers
{
+ public IntPtr GetOrCreateComInterfaceForObject<TInterface>(object instance, CreateComInterfaceFlags flags);
}
- Failing to QI for
TInterface will trigger an InvalidCastException.
- Failing to QI for
TInterface will still insert into the map.
API Usage
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
[assembly: DisableRuntimeMarshalling]
namespace ConsoleAotAuthor
{
internal partial class Program
{
static void Main()
{
var cw = new StrategyBasedComWrappers();
var foo = new Foo();
// Will throw if foo doesn't QI for IFoo.
nint ifoo = cw.GetOrCreateComInterfaceForObject<Foo, IFoo>(foo, CreateComInterfaceFlags.None);
GivePointerToComInterface(ifoo);
}
[LibraryImport("Dll1.dll")]
private static partial void GivePointerToComInterface(nint comObject);
}
[GeneratedComInterface, Guid("217104c3-ce28-4d13-a32e-ef65ee75edf1")]
public partial interface IFoo
{
void Method(int i);
}
[GeneratedComClass]
public partial class Foo : IFoo
{
public void Method(int i) => Console.WriteLine(".NET i:" + i);
}
}
Alternative Designs
No response
Risks
No response
Background and motivation
It would be nice to have some wrappers that would return other interfaces pointers, something like:
that would do the QI so I could call it like this:
As a "frequent COM flyer", It's quite perturbing to have to juggle between
ComWrappersandMarshalclasses, actually it would be nice with all that new code to be able to avoid usingMarshalcompletely :-)Originally posted by @smourier in #106978 (comment)
public abstract partial class ComWrappers { + public bool TryGetComInstance<TInterface>(object instance, CreateComInterfaceFlags flags, out IntPtr result); }This could also be an auto-generated method that would be provided on a derived
ComWrappersinstance. Looking up the IID onTInterfacewould need to be AOT friendly, which meanstypeof(TInterface).GUIDis out.API Proposal
The below API is modified from the OP proposal to align with existing API shape and motivating example below.
public abstract class ComWrappers { public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags); + public IntPtr GetOrCreateComInterfaceForObject(object instance, CreateComInterfaceFlags flags, in Guid interfaceId); }public class StrategyBasedComWrappers { + public IntPtr GetOrCreateComInterfaceForObject<TInterface>(object instance, CreateComInterfaceFlags flags); }TInterfacewill trigger anInvalidCastException.TInterfacewill still insert into the map.API Usage
Alternative Designs
No response
Risks
No response