COM interface declarations

When creating COM interface declarations in C #, are there any "rules" that you must adhere to? I think there is and would like to have some information about this. For example, I am playing around with the ITaskbarList, ITaskbarList2 and ITaskbarList3 interfaces and it seems to me that I

  • You must declare the order of the members in the implementation control exactly in the order in which they appear in the unmanaged interface declaration.

For example, the following looks just fine

[ComImport]
[Guid("56FDF342-FD6D-11D0-958A-006097C9A090")] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITaskbarList
{
    void HrInit();
    void AddTab([In] IntPtr hwnd);
    void DeleteTab([In] IntPtr hwnd);
    void ActivateTab([In] IntPtr hwnd);
    void SetActiveAlt([In] IntPtr hwnd);
}

      

While reordering of members breaks functionality

[ComImport]
[Guid("56FDF342-FD6D-11D0-958A-006097C9A090")] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITaskbarList
{
    void DeleteTab([In] IntPtr hwnd);
    void HrInit();
    void AddTab([In] IntPtr hwnd);
    void SetActiveAlt([In] IntPtr hwnd);
    void ActivateTab([In] IntPtr hwnd);
}

      

  • You must declare inherited unmanaged interfaces in a single managed interface declaration instead of using inherited managed interfaces. I want to declare each of the unmanaged interfaces in its own managed interface (complete with Guid attributes, etc.) and use inbetween inheritance, instead of having to update parent declarations in every new interface.

For example this doesn't work

[ComImport]
[Guid("56FDF342-FD6D-11D0-958A-006097C9A090")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITaskbarList
{
    void HrInit();
    void AddTab([In] IntPtr hwnd);
    void DeleteTab([In] IntPtr hwnd);
    void ActivateTab([In] IntPtr hwnd);
    void SetActiveAlt([In] IntPtr hwnd);
}

[ComImport]
[Guid("602D4995-B13A-429B-A66E-1935E44F4317")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITaskbarList2
    : ITaskbarList
{
    void MarkFullscreenWindow(
        [In] IntPtr hwnd,
        [In, MarshalAs(UnmanagedType.Bool)] bool fullscreen);
}

      

Instead, I am forced to do the following

[ComImport]
[Guid("602D4995-B13A-429B-A66E-1935E44F4317")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITaskbarList2
{
    void HrInit();
    void AddTab([In] IntPtr hwnd);
    void DeleteTab([In] IntPtr hwnd);
    void ActivateTab([In] IntPtr hwnd);
    void SetActiveAlt([In] IntPtr hwnd);
    void MarkFullscreenWindow(
        [In] IntPtr hwnd,
        [In, MarshalAs(UnmanagedType.Bool)] bool fullscreen);
}

      

I. Declare it in the same interface while still respecting member order.

So what are the guidelines for declaring managed interfaces for their unmanaged counterparts? Is there anyway to achieve what I want is interface inheritance on the managed side + declare the members in whatever order I want (I really just want to sort them alphabetically)

+2


source to share


1 answer


Your openings are triggered by the same: vtables. You cannot change the order of the vtable, and interfaces inheriting from other interfaces always have all the underlying entries in the vtable. So, the rules you are looking for are "make sure the vtable is the same".



+3


source







All Articles