简体   繁体   中英

C# COM Interface Inheritance

I have the following (DirectShow related) COM interface in C++ that I need to call in C#.

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

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

I declared this in C# as the following but it crashes out with Access Violation when IFoo.Foo() is called. Works fine with IBar.Bar() is called though. What is the correct way to write the equivalent interface in 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
}

The vtables must be incompatible in C# vs C++ for inherited COM interface. Is there a way to tell C# to adhere to the C++ declaration?

Your C# declaration of IFoo should look like this:

[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
}

In other words, you should replicate methods (and v-table layout) of IBar for IFoo instead of deriving from it, to make the .NET COM interop marshaller happy. The same is possible in C++, although it's more natural to use C++ inheritance there. For .NET COM interop though, it's a necessity.

This technique is widely used in the .NET Reference Source, eg for IOleInPlaceActiveObject , which is derived from IOleWindow .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM