Is there a need to re-specify the Com interface type attribute if it is inherited from another Com interface in which the type has already been specified?

Example:

 [ComImport] [Guid("aec22fb8-76f3-4639-9be0-28eb43a67a2e")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDXGIObject { long SetPrivateData([In] ref Guid name, [In] uint dataSize, IntPtr dataPtr); long SetPrivateDataInterface([In] ref Guid name, [In] [MarshalAs(UnmanagedType.IUnknown)] object unknownInterfaceObject); long GetPrivateData([In] ref Guid name, out int dataSize, out IntPtr dataPtr); long GetParent([In] ref Guid rIId, [Out] out object pParent); } 

Further, his successor will be IDXGIFactory :

 /// <inheritdoc cref="IDXGIObject"/> /> /// <summary> /// An IDXGIFactory interface implements methods for generating DXGI objects (which handle fullscreen transitions). /// </summary> [ComImport] [Guid("7b7166ec-21c7-44ae-b21a-c9ae321ae369")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDXGIFactory : IDXGIObject { /// <summary> /// Enumerates the adapters (video cards). /// </summary> [PreserveSig] HResult EnumAdapters(uint numAdapter, [MarshalAs(UnmanagedType.IUnknown)] out object adapter); /// <summary> /// Allows DXGI to monitor an application's message queue for the alt-enter key sequence (which causes the application /// to switch from windowed to fullscreen or vice versa). /// </summary> [PreserveSig] HResult MakeWindowAssociation(IntPtr windowHandle, uint flags); /// <summary> /// Get the window through which the user controls the transition to and from fullscreen. /// </summary> [PreserveSig] HResult GetWindowAssociation(out IntPtr outHandleWindow); /// <summary> /// Creates a swap chain. /// </summary> [PreserveSig] HResult CreateSwapChain(IntPtr lpIUnknown, IntPtr ptr, out IntPtr outPtr); /// <summary> /// Create an adapter interface that represents a software adapter. /// </summary> [PreserveSig] HResult CreateSoftwareAdapter(IntPtr moduleHandle, out IntPtr outPtr); } 

Do you need to re-write the attribute

 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 

for the heir interface, if it is also essentially IUnknown ?

    2 answers 2

    Needed because InterfaceTypeAttribute is defined as not inheritable:

    [System.AttributeUsage (System.AttributeTargets.Interface, Inherited = false )]
    [System.Runtime.InteropServices.ComVisible (true)]
    public sealed class InterfaceTypeAttribute: Attribute

    • Hmm, I marked all the objects, the application began to fall ... - LLENN
    • @LLENN show the full definition of the derived interface - MSDN.WhiteKnight
    • Added completely one of the derived interfaces. - LLENN Nov.
    • And the result of the execution will be: 8015948170355802112 - LLENN
    • @LLENN The methods of the base interface should be duplicated in the heir interface. Inheritance in COM Interop does not work as expected. Base class methods are not automatically added to VTable. Attributes are indirectly related to this. - MSDN.WhiteKnight 5:26

    Through some manipulations, it was possible to find out, it is imperative to observe the following rules:

    1. The inherited object must override the interface declaration from which it is inherited, before the methods of the current method, i.e. before their ads. (Thanks for the tip @ MSDN.WhiteKnight ).

    2. The interface successor must necessarily have the attribute [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] , otherwise we will have problems with memory access.

    3. The interface inherits from the interface which is basic for it only for the convenience of working with these interfaces.

    Thus, the basic interface, for example, in this case, this IDXGIObject looks like this:

     /// <summary> /// An IDXGIObject interface is a base interface for all DXGI objects; IDXGIObject supports associating caller-defined /// (private data) with an object and retrieval of an interface to the parent object. /// </summary> [Guid("aec22fb8-76f3-4639-9be0-28eb43a67a2e")] [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDXGIObject { /// <summary> /// Sets an IUnknown interface as private data; this associates application-defined data with the object. /// </summary> [PreserveSig] HResult SetPrivateData(ref Guid name, uint dataSize, IntPtr dataPtr); /// <summary> /// Set an interface in the object's private data. /// </summary> [PreserveSig] HResult SetPrivateDataInterface(ref Guid name, [MarshalAs(UnmanagedType.IUnknown)] object unknownInterfaceObject); /// <summary> /// Get a pointer to the object's data. /// </summary> [PreserveSig] HResult GetPrivateData(ref Guid name, out int dataSize, out IntPtr dataPtr); /// <summary> /// Gets the parent of the object. /// </summary> [PreserveSig] HResult GetParent(ref Guid rIId, out object pParent); } 

    Further, from it, for example, the IDXGIFactory definition is inherited IDXGIFactory you must set it strictly like this:

     /// <inheritdoc /> /// <summary> /// An <see cref="T:Himiko.DXGI.Interfaces.IDXGIFactory" /> interface implements methods for generating DXGI objects (which handle fullscreen /// transitions). /// </summary> [Guid("7b7166ec-21c7-44ae-b21a-c9ae321ae369")] [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDXGIFactory : IDXGIObject { /// <summary> /// Sets an IUnknown interface as private data; this associates application-defined data with the object. /// </summary> [PreserveSig] new HResult SetPrivateData(ref Guid name, uint dataSize, IntPtr dataPtr); /// <summary> /// Set an interface in the object's private data. /// </summary> [PreserveSig] new HResult SetPrivateDataInterface(ref Guid name, [MarshalAs(UnmanagedType.IUnknown)] object unknownInterfaceObject); /// <summary> /// Get a pointer to the object's data. /// </summary> [PreserveSig] new HResult GetPrivateData(ref Guid name, out int dataSize, out IntPtr dataPtr); /// <summary> /// Gets the parent of the object. /// </summary> [PreserveSig] new HResult GetParent(ref Guid rIId, out object pParent); /// <summary> /// Enumerates the adapters (video cards). /// </summary> [PreserveSig] HResult EnumAdapters(uint numAdapter, [MarshalAs(UnmanagedType.IUnknown)] out object adapter); /// <summary> /// Allows DXGI to monitor an application's message queue for the alt-enter key sequence (which causes the application /// to switch from windowed to fullscreen or vice versa). /// </summary> [PreserveSig] HResult MakeWindowAssociation(IntPtr windowHandle, uint flags); /// <summary> /// Get the window through which the user controls the transition to and from fullscreen. /// </summary> [PreserveSig] HResult GetWindowAssociation(out IntPtr outHandleWindow); /// <summary> /// Creates a swap chain. /// </summary> [PreserveSig] HResult CreateSwapChain(object iUnknown, ref DxgiSwapChainDesc swapChainDesc, [MarshalAs(UnmanagedType.IUnknown)] out object dxgiSwapChainObject); /// <summary> /// Create an adapter interface that represents a software adapter. /// </summary> [PreserveSig] HResult CreateSoftwareAdapter(IntPtr moduleHandle, out IntPtr outPtr); } 

    All problems have exhausted themselves, and the code began to work as it should.