Объявления COM-интерфейса
-
07-07-2019 - |
Вопрос
Существуют ли какие-либо «правила» при создании объявлений 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);
}
То есть объявить это в одном интерфейсе, при этом принимая во внимание порядок участников.
Итак, каковы рекомендации по объявлению управляемых интерфейсов для их неуправляемых аналогов?Есть ли способ достичь того, чего я хочу, это наследование интерфейса на управляемой стороне + объявить члены в любом порядке, который я хочу (на самом деле я просто хочу отсортировать их в алфавитном порядке)
Решение
Ваши открытия вызваны тем же:виртуальные таблицы.Вы не можете изменить порядок виртуальной таблицы, а интерфейсы, которые наследуются от других интерфейсов, также всегда имеют все базовые записи в виртуальной таблице.Итак, правила, которые вы ищете: «убедитесь, что виртуальная таблица одинакова».