Pregunta

Al crear declaraciones de interfaz COM en C #, ¿hay alguna "regla"? tienes que seguir? Creo que hay y me gustaría obtener información al respecto. Por ejemplo, estoy jugando con las interfaces ITaskbarList, ITaskbarList2 e ITaskbarList3 y me parece que yo

  • Tiene que declarar el orden de los miembros en la implementación de gestión exactamente en el orden en que aparecen en la declaración de interfaz no administrada.

Por ejemplo, lo siguiente parece funcionar bien

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

Al reordenar los miembros se rompe la funcionalidad

[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);
}
  • Tiene que declarar las interfaces no administradas heredadas en una sola declaración de interfaz administrada en lugar de usar la herencia en las interfaces administradas. Quiero declarar cada una de las interfaces no administradas en su propia interfaz administrada (completa con atributos Guid, etc.) y usar la herencia entre ellas, en lugar de volver a declarar las declaraciones principales en cada nueva interfaz.

Por ejemplo, esto no parece funcionar

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

En cambio, me veo obligado a hacer lo siguiente

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

Es decir, declararlo en una única interfaz sin dejar de tener en cuenta el pedido de miembro.

¿Cuáles son las pautas para declarar interfaces administradas para sus contrapartes no administradas? ¿Hay alguna forma de lograr lo que quiero? Interfaz de herencia en el lado administrado + declarar a los miembros en el orden que quiera (realmente solo quiero ordenarlos alfabéticamente)

¿Fue útil?

Solución

Tus descubrimientos son causados ??por lo mismo: vtables. No puede cambiar el orden de vtable, y las interfaces que heredan de otras interfaces siempre tienen todas las entradas base en la vtable también. Por lo tanto, las reglas que está buscando es "asegurarse de que la vtable sea la misma".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top