何时使用全局接口表

如果在进程中单元之间多次取消封送接口指针,则可以使用 IGlobalInterfaceTable 接口。 如果使用其他技术,则每次都必须重新封送。

注意

如果接口指针仅取消封送一次,则可能需要使用 CoMarshalInterThreadInterfaceInStream 函数。 它还可用于将接口指针从一个线程传递到同一进程中的另一个线程。

 

IGlobalInterfaceTable 接口也简化了程序员以前遇到的另一个难题。 当下列条件适用时,会出现此问题:

  • 进程内敏捷对象聚合了自由线程封送拆收器。
  • 同一敏捷对象还包含(作为成员变量)接口指针,这些指针指向不敏捷且不聚合自由线程封送拆收器的其他对象。

在这种情况下,如果外部对象被封送到另一个单元,并且应用程序对其调用,并且该对象尝试对其任何成员变量接口指针进行调用,这些指针不是自由线程的,或者是对其他单元中的对象的代理,则它可能会得到不正确的结果或错误 RPC_E_WRONG_THREAD。 之所以发生此错误,是因为内部接口设计为只能从首次存储在成员变量中的单元中调用。

若要解决此问题,聚合自由线程封送拆收器的外部对象应在内部接口上调用 IGlobalInterfaceTable::RegisterInterfaceInGlobal,并将生成的 Cookie 存储在其成员变量中,而不是存储实际的接口指针。 当外部对象想要调用内部对象的接口指针时,它应调用 IGlobalInterfaceTable::GetInterfaceFromGlobal,使用返回的接口指针,然后释放它。 当外部对象消失时,它应调用 IGlobalInterfaceTable::RevokeInterfaceFromGlobal 从全局接口表中删除接口。

创建全局接口表