Объявления интерфейса COM - PullRequest
2 голосов
/ 16 сентября 2009

При создании объявлений интерфейса COM в C # есть ли какие-то "правила", которые вы должны придерживаться? Я думаю, что есть и хотели бы получить некоторую информацию об этом. Например, я играю с интерфейсами ITaskbarList, ITaskbarList2 и ITaskbarList3, и мне кажется, что я

  • Должен объявлять порядок членов в реализации управления именно в том порядке, в котором они появляются в объявлении неуправляемого интерфейса.

Например, кажется, что следующее работает нормально

[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("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);
}
  • Необходимо объявлять унаследованные неуправляемые интерфейсы в одном объявлении управляемого интерфейса вместо использования наследования на управляемых интерфейсах. Я хочу объявить каждый из неуправляемых интерфейсов в их собственном управляемом интерфейсе (в комплекте с атрибутами Guid и т. Д.) И использовать наследование между ними вместо повторного выделения родительских объявлений в каждом новом интерфейсе.

Например, это не похоже на работу

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

Вместо этого я вынужден сделать следующее

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

Т.е. мы объявляем это в едином интерфейсе, все еще принимая во внимание порядок членов.

Итак, каковы рекомендации по объявлению управляемых интерфейсов для их неуправляемых аналогов? Есть ли в любом случае, чтобы достичь того, что я хочу, это наследование интерфейса на управляемой стороне + объявить членов в любом порядке, который я хочу (я действительно просто хочу отсортировать их в алфавитном порядке)

1 Ответ

3 голосов
/ 16 сентября 2009

Ваши открытия вызваны тем же: vtables. Вы не можете изменить порядок vtable, и интерфейсы, которые наследуются от других интерфейсов, всегда имеют также все базовые записи в vtable. Итак, правила, которые вы ищете: «убедитесь, что vtable такой же».

...