本文介绍了如何声明和实现,从另外一个COM接口继承在C#中的COM接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解什么是正确的,为什么来实现从C#代码COM接口。当接口不从其他基接口继承它很简单。像这样的:

I'm trying to understand what is the correct why to implement COM interfaces from C# code. It is straightforward when the interface doesn't inherit from other base interface. Like this one:

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



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

However things start to become weired when I need to implement an interface that inherits from other COM interfaces. For example, if I implement the IPersistFolder2 interface which inherits from IPersistFolder which inherits from IPersist as I usually on C# code:

[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 如下:

The operating system is not able to call the methods on my object implementation. When I'm debugging I can see the constructor of my IPersistFolder2 implementation is called many times, however the interface methods I've implemented aren't called. I'm implementing the IPersistFolder2 as follows:

[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接口进口为遵循,它的工作原理:

What seems strange is when I declare the COM interface imports as follow, it works:

[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接口这种方式(hidding底座接口的方法使用)。也许它关系到IUnknown的工作方式。有谁知道什么是实现在C#中,从其他COM接口,为什么?

I don't know why it works when I declare the COM interfaces that way (hidding the base interface methods using new). Maybe it is related to the way IUnknown works. Does anyone know what is the correct way of implementing COM interfaces in C# that inherits from other COM interfaces and why?

推荐答案

巧妙继承了COM接口的正确方法使用new关键字,那的确会解决这个问题。这里的问题是,COM不支持继承。它是在IDL只是符号上的简洁,使它看起来像它。在现实中,一个接口v表必须聚合所有的继承的基本接口。换句话说,对于IPersistFolder接口,它必须复制v表时隙为3 IUnknown方法和的IPersist ::的GetClassID方法。 CLR获得照顾的IUnknown的BTW。

Neat trick with the new keyword, that would indeed fix the problem. The issue here is that COM doesn't support inheritance. It is merely notational convenience in IDL to make it look like it does. In reality, an interface v-table must aggregate all the "inherited" base interfaces. In other words, for the IPersistFolder interface it must replicate the v-table slots for the 3 IUnknown methods and the IPersist::GetClassID method. The CLR takes care of IUnknown btw.

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

The v-table that .NET builds is not compatible with this layout, it doesn't replicate the base class method slots.

这篇关于如何声明和实现,从另外一个COM接口继承在C#中的COM接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 03:29