代码之家  ›  专栏  ›  技术社区  ›  TheCodeJunkie

COM接口声明

  •  2
  • TheCodeJunkie  · 技术社区  · 15 年前

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

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

    那么,为非托管接口声明托管接口的准则是什么呢?有没有实现我想要的,托管端的IT接口继承+按我想要的任何顺序声明成员(我真的只想按字母顺序排序)

    1 回复  |  直到 9 年前
        1
  •  3
  •   i_am_jorf    15 年前

    你的发现是由同一件事引起的:vTables。您不能更改vtable顺序,从其他接口继承的接口也总是在vtable中具有所有基本条目。所以,您要寻找的规则是“确保vtable是相同的”。