准确导入的组件中的CoClass接口是什么?

时间:2014-01-03 15:34:07

标签: c# .net com com-interop tlbimp

使用tlbimp.exe工具导入基本类型库始终为每个coclass创建一个界面。例如,此IDL描述

interface IFoo : IUnknown
{
    HRESULT DoSomething();
}

coclass Bar
{
    [default] interface IFoo;
}

结果:

  • 接口IFoo,作为COM接口的表示,
  • 一个类BarClass,作为COM coclass和
  • 的表示
  • 接口Bar,使用CoClassAttribute注释。

BarIFoo的GUID相等。关于此主题的MSDN个州:

  

此接口与coclass的默认接口具有相同的IID。通过此接口,客户端始终可以注册为事件接收器。

这是我在这个主题上唯一发现的东西。我知道,由于CoClassAttribute,我可以使用该接口来创建实际类的实例。我也知道(实际上)我可以简单地使用BarClass来创建一个新的类实例。我不明白的是,为什么导入过程会生成Bar接口,即使coclass没有定义事件源,也没有事件接收器可以连接到它。

在此示例中是否可以删除Bar接口 1 ,还是存在其他风险,我还没有考虑过?

1 例如disassembling the interop assembly

1 个答案:

答案 0 :(得分:5)

你的名字错了,这无助于理解正在发生的事情。类型库中的Bar coclass生成Bar接口和BarClass类,没有“FooBar”。

这只是类型库自动生成的额外粘合剂,可以使移植代码更容易。对于VB6代码尤为重要,它对COM对象模型采取了很多自由。 VB6程序使用coclass,就好像它是一个带有实现的真实类。 COM中没有这样的东西,coclass是类的不透明占位符,它是完成所有工作的接口。 VB6从不支持接口的概念,因此无法在代码中直接建模COM。

VB6编译器本身从代码中的Class关键字生成一个coclass,并生成一个包含实际方法和属性的接口。该接口是隐藏,它具有相同的类名,但带有前导下划线。按照惯例,这会导致对象浏览器隐藏接口。因此,当用VB6编写时,Bar coclass将生成_Bar接口。

因此,转换后的VB6程序将在任何地方使用Bar。除非“Bar”被“IFoo”取代,否则不会编译。合成的Bar界面得到了拯救,避免了这种需要。

还有两个问题需要解决,由合成BarClass类型修复。 New Bar()将无法编译,因为创建接口实例是不合法的。编译器解决了这个问题,它自动用“BarClass”替换“Bar”。这是[CoClass]属性的实际角色,它提供与接口关联的类的名称。事件是一个问题,它们通过调度接口在COM中实现。同样是一个单独的界面,在引擎盖下有一个用于订阅事件的复杂机制(IConnectionPoint等)。合成的BarClass使它们成为真正的.NET事件。