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)

Foi útil?

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."

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top