COM interface de declarações
-
07-07-2019 - |
Pergunta
Ao criar declarações de interface COM em C # existem quaisquer "regras" que você tem que ficar com? Eu acho que existem e gostaria de obter algumas informações sobre ele. Por exemplo, eu estou brincando ao redor com as interfaces ITaskbarList, ITaskbarList2 e ITaskbarList3 e parece-me que eu
- tem que declarar a ordem dos membros na implementação consegue exatamente na ordem em que aparecem na declaração de interface não gerenciado.
Por exemplo, os seguintes parece funcionar muito bem
[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);
}
Enquanto reordenar os membros quebras a funcionalidade
[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);
}
- tem que declarar herdou as interfaces não gerenciados em uma única declaração interface gerenciada em vez de usar a herança nas interfaces gerenciadas. Quero declarar cada uma das interfaces não gerenciados em sua própria interface gerenciada (com atributos Guid etc) e usar a herança inbetween então, em vez de redeclaring as declarações mãe em cada nova interface.
Por exemplo, este não parece trabalho
[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);
}
Em vez disso eu sou obrigado a fazer o seguinte
[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);
}
ou seja declará-lo em uma única interface, enquanto ainda tendo a ordem membro em consideração.
Então, quais são as diretrizes para declarar interfaces de gerenciados para suas contrapartes não gerenciados? Existe uma maneira de conseguir o que eu quero, é interface de herança no lado gerenciado + declarar os membros em qualquer ordem que eu quero (Eu realmente só quero classificá-los em ordem alfabética)
Solução
As suas descobertas são causadas pela mesma coisa: vtables. Você não pode alterar a ordem vtable, e as interfaces que herdam de outras interfaces sempre têm todas as entradas de base na vtable bem. Assim, as regras que você está procurando é "garantir que o vtable é o mesmo."