C#接口继承

本文关键字:继承 接口 | 更新日期: 2023-09-27 18:25:04

我在C++中有以下(与DirectShow相关)COM接口,需要在C#中调用。

[uuid("...")] : public IUnknown
interface IBar
{
    STDMETHOD(Bar)(void);
}
[uuid("...")]
interface IFoo : public IBar
{
    STDMETHOD(Foo)(void);
}

我在C#中声明如下,但当调用IFoo.Foo()时,它会因访问冲突而崩溃。与IBar配合使用很好。不过调用了Bar()。用C#编写等效接口的正确方法是什么?

[ComImport, Guid("...)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[SuppressUnmanagedCodeSecurity]
public interface IBar
{
    [PreserveSig] int Bar(); // Calling this is OK
}
[ComImport, Guid("...)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[SuppressUnmanagedCodeSecurity]
public interface IFoo : IBar
{
    [PreserveSig] int Foo(); // Calling this crashes
}

对于继承的COM接口,vtables在C#与C++中必须不兼容。有没有一种方法可以告诉C#遵守C++声明?

C#接口继承

IFoo的C#声明应该如下所示:

[ComImport, Guid("...)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[SuppressUnmanagedCodeSecurity]
public interface IFoo
{
    [PreserveSig] int Bar(); // Calling this is OK
    [PreserveSig] int Foo(); // Calling this should also be OK
}

换句话说,您应该为IFoo复制IBar的方法(和v-table布局),而不是从中派生,以使.NET COM互操作整理器满意。在C++中也是可能的,尽管在那里使用C++继承更自然。不过,对于.NET COM互操作来说,这是必要的。

此技术广泛用于.NET参考源,例如源自IOleWindow的IOleInPlaceActiveObject。