类的默认封送处理

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

将类传递给 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 的一般包装类来包装接口。

请参见

概念

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

方向特性

复制和锁定

其他资源

默认封送处理行为