2010-06-01 48 views
5

我想了解什么是正确的,为什么要从C#代码实现COM接口。当接口不从其他基本接口继承时,它很简单。像这样的:如何在C#上声明和实现COM接口,并从另一个COM接口继承?

[ComImport, Guid("2047E320-F2A9-11CE-AE65-08002B2E1262"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IShellFolderViewCB 
{ 
    long MessageSFVCB(uint uMsg, int wParam, int lParam); 
} 

然而,事情开始的时候我需要实现与其他COM接口继承的接口成为weired。例如,如果我实现IPersistFolder2接口从IPersistFolderIPersist继承,因为我通常是在C#代码继承:

[ComImport, Guid("0000010c-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IPersist 
{ 
    void GetClassID([Out] out Guid classID); 
} 

[ComImport, Guid("000214EA-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IPersistFolder : IPersist 
{ 
    void Initialize([In] IntPtr pidl); 
} 

[ComImport, Guid("1AC3D9F0-175C-11d1-95BE-00609797EA4F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IPersistFolder2 : IPersistFolder 
{ 
    void GetCurFolder([Out] out IntPtr ppidl); 
} 

操作系统是无法调用我的对象实现的方法。当我调试时,我可以看到我的IPersistFolder2实现的构造函数被多次调用,但是我实现的接口方法未被调用。我执行IPersistFolder2如下:

[Guid("A4603CDB-EC86-4E40-80FE-25D5F5FA467D")] 
public class PersistFolder: IPersistFolder2 
{ 
    void IPersistFolder2.GetClassID(ref Guid classID) { ... } 
    void IPersistFolder2.Initialize(IntPtr pidl) { ... } 
    void IPersistFolder2.GetCurFolder(out IntPtr ppidl) { ... } 
} 

什么似乎很奇怪的是当我宣布COM接口进口的追随,它的工作原理:

[ComImport, Guid("0000010c-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
internal interface IPersist 
{ 
    void GetClassID([Out] out Guid classID); 
} 

[ComImport, Guid("000214EA-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
internal interface IPersistFolder : IPersist 
{ 
    new void GetClassID([Out] out Guid classID); 
    void Initialize([In] IntPtr pidl); 
} 

[ComImport, Guid("1AC3D9F0-175C-11d1-95BE-00609797EA4F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
internal interface IPersistFolder2 : IPersistFolder 
{ 
    new void GetClassID([Out] out Guid classID); 
    new void Initialize([In] IntPtr pidl); 
    void GetCurFolder([Out] out IntPtr ppidl); 
} 

我不知道为什么它的工作原理,当我以这种方式声明COM接口(使用new隐藏基本接口方法)。也许它与IUnknown的工作方式有关。有谁知道在C#中实现COM接口的正确方式是从其他COM接口继承的,为什么?

+0

投票给你,告诉我如何“导入”IPersist。 http://stackoverflow.com/questions/1253368/c-get-progid-from-com-object使用它,但没有提及如何添加引用。 – 2010-08-09 05:53:25

+0

我遇到了同样的问题,并能够使用'新'关键字修复它。 感谢@Hans Passant aswell :) – 2015-05-05 07:27:35

回答

3

与新的关键字整洁的把戏,这将确实解决问题。这里的问题是COM不支持继承。 IDL中的符号方便性使它看起来像它一样。实际上,接口v-表必须聚合所有“继承”的基础接口。换句话说,对于IPersistFolder接口,它必须复制3个IUnknown方法和IPersist :: GetClassID方法的v表插槽。 CLR照顾IUnknown btw。

.NET构建的v表与此布局不兼容,它不会复制基类方法插槽。