在 C# 中创建 COM 接口声明时,是否有必须遵守的“规则”?我认为有并且想获得一些相关信息。例如,我正在摆弄 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);
}

即在单个接口中声明它,同时仍然考虑成员顺序。

那么,为非托管接口声明托管接口的准则是什么?无论如何,有没有办法实现我想要的,它在托管端接口继承+以我想要的任何顺序声明成员(我真的只想按字母顺序对它们进行排序)

有帮助吗?

解决方案

你们的发现都是由同一件事引起的:虚拟表。您无法更改 vtable 顺序,并且从其他接口继承的接口也始终拥有 vtable 中的所有基本条目。因此,您要寻找的规则是“确保 vtable 相同”。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top