Вопрос

Существуют ли какие-либо «правила» при создании объявлений 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);
}

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

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

Это было полезно?

Решение

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top