类的默认封送处理

更新:2007 年 11 月

类只能由 COM Interop 封送,且始终作为接口进行封送。在某些情况下,用于封送类的接口称为类接口。有关使用自己选择的接口来重写类接口的信息,请参见类接口简介

将类传递给 COM

将托管类传递给 COM 时,Interop 封送拆收器会自动用 COM 代理包装该类,并将该代理所产生的类接口传递给 COM 方法调用。该代理然后将类接口上的所有调用委托回托管对象。该代理还会公开未由该类显式实现的其他接口。该代理会代表类自动实现 IUnknownIDispatch 这样的接口。

将类传递给 .NET 代码

Coclass 通常不用作 COM 中的方法参数。相反,通常会传递一个默认接口来代替 Coclass。

当将一个接口传递到托管代码中时,Interop 封送拆收器负责使用适当的包装来包装该接口,并将该包装传递给托管方法。确定使用哪一个包装可能会有一定的困难。无论 COM 对象实现多少个接口,COM 对象的每个实例都有一个唯一的包装。例如,实现五个不同接口的单个 COM 对象只有一个包装。同一个包装将公开所有这五个接口。如果创建了 COM 对象的两个实例,则会创建该包装的两个实例。

若要使包装在其生存期内维持同一个类型,那么在第一次通过 Interop 封送拆收器传递由对象公开的接口时,该封送拆收器必须标识正确的包装。封送拆收器通过查看对象实现的接口之一来标识对象。

例如,封送拆收器确定应当使用类包装来包装传递到托管代码中的接口。当第一次通过封送拆收器传递接口时,封送拆收器将检查该接口是否来自已知对象。在下列两种情况下将进行这样的检查:

  • 接口正被在其他地方传递给 COM 的另一托管对象实现。封送拆收器可以很容易地标识托管对象所公开的接口,并能够将该接口与提供该实现的托管对象相匹配。托管对象然后被传递给方法,而不需要任何包装。

  • 已被包装的对象正在实现接口。若要确定情况是否如此,封送拆收器将向对象查询其 IUnknown 接口并将返回的接口与已被包装的其他对象的接口相比较。如果该接口与另一包装的接口相同,则对象具有同一标识,而现有的包装将被传递给方法。

如果接口不是来自已知对象,则封送拆收器将执行下列操作:

  1. 封送拆收器向该对象查询 IProvideClassInfo2 接口。如果提供了此接口,则封送拆收器将使用从 IProvideClassInfo2.GetGUID 返回的 CLSID 来标识提供此接口的 Coclass。如果以前已经注册了程序集,那么封送拆收器就可以通过该 CLSID 从注册表中找到包装。

  2. 封送拆收器向接口查询 IProvideClassInfo 接口。如果提供了此接口,封送拆收器将使用从 IProvideClassInfo.GetClassinfo 返回的 ITypeInfo 来确定公开此接口的类的 CLSID。封送拆收器可以使用该 CLSID 找到包装的元数据。

  3. 如果封送拆收器仍然无法标识类,它将使用名为 System.__ComObject 的一般包装类来包装接口。

请参见

概念

可直接复制到本机结构中的类型和非直接复制到本机结构中的类型

方向属性

复制和锁定

其他资源

默认封送处理行为