2009-09-15 103 views
2

当在C#中创建COM接口声明时,是否有任何“规则”必须坚持?我认为有,并希望得到一些信息。比如我玩弄与周围的ITaskbarList,ITaskbarList2和ITaskbarList3接口,在我看来,我COM接口声明

  • 必须声明成员的顺序应依次正是管理的实现,它们出现在非托管接口声明。

例如下面似乎工作就好

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

即在一个界面中声明它同时还服用会员订单考虑。

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

回答

3

您的发现是由同样的事情引起的:vtables。您无法更改vtable顺序,并且从其他接口继承的接口始终也具有vtable中的所有基本条目。所以,你要找的规则是“确保vtable是一样的。”

+0

因此,.net不会放纵基于名称的vtable条目的自动映射吗?无论如何配置使用属性等?此外,为什么继承没有工作? Surly它会将vtables连接在继承链上?首先是ITaskbarList的条目,然后是ITaskbarList2,然后是ITaskbarList3 ..或者,我是否只结束ITaskbarList3中最后一个接口的条目而不管继承? – TheCodeJunkie 2009-09-15 20:38:53

+3

从其他接口继承的接口始终拥有vtable中的所有基本条目 这不意味着如果每个接口中成员的顺序都是正确的,那么接口的vtable条目继承另一个接口,最终会正确吗? – TheCodeJunkie 2009-09-15 20:40:36

+2

我会回答我自己的跟进问题。 .NET interop不支持接口继承,因此您必须在子接口中重新定义父接口成员。 – TheCodeJunkie 2009-09-15 21:51:04