如何手动编组.NET对象作为双COM接口?

时间:2017-06-12 19:22:54

标签: c# .net com idispatch

我编写了一些C#代码,它使用IDispatch将.NET对象作为Marshal.GetIDispatchForObject指针返回到非托管代码,但是,此对象还实现了其他(非.NET定义的)COM接口。 在非托管世界QueryInterface中,这些接口工作正常,但是,调用它们的方法永远不会破坏我的.NET代码,似乎只返回默认值(0)。

是否可以将.NET对象作为双接口进行生成,以便可以通过IDispatch或通过查询特定接口来使用它?我的类型是公开的ComVisible,我尝试运用[ClassInterface(ClassInterfaceType.AutoDual)]但没有运气。

我使用UnmanagedType.Interface封送处理工作没有问题,但支持IDispatch似乎也有问题。如果有 easy 方式来"手动"实施IDispatch这也是一个可以接受的解决方案。

1 个答案:

答案 0 :(得分:1)

您可以使用ICustomQueryInterface interface。它将允许您“手动”返回IUnknown接口,并仍然受益于.NET提供的IDispatch实现。 因此,例如,如果您有一个非托管的IUnknown接口“IMyUnknown”,其中包含一个方法(示例中名为“MyUnknownMethod”),您可以像这样声明您的.NET类:

[ComVisible(true)]
public class Class1 : ICustomQueryInterface, IMyUnknown
{
    CustomQueryInterfaceResult ICustomQueryInterface.GetInterface(ref Guid iid, out IntPtr ppv)
    {
        if (iid == typeof(IMyUnknown).GUID)
        {
            ppv = Marshal.GetComInterfaceForObject(this, typeof(IMyUnknown), CustomQueryInterfaceMode.Ignore);
            return CustomQueryInterfaceResult.Handled;
        }

        ppv = IntPtr.Zero;
        return CustomQueryInterfaceResult.NotHandled;
    }

    // an automatic IDispatch method
    public void MyDispatchMethod()
    {
       ...
    }

    // the IMyUnknown method
    // note you can declare that method with a private implementation
    public void MyUnknownMethod()
    {
       ...
    }
}