如何通过在 Visual C++ 中单元封送接口

    技术2022-05-11  2

    一个 Single-Threaded 单元 (STA) 是一个线程的已初始化,但有 CoInitialize() 或 CoInitializeEx (NULL,COINIT_APARTMENTTHREADED)。 此外,使用 COM 的相同的过程中的任何其他线程还必须调用 CoInitialize() 或 CoInitializeEx() 为它的线程初始化 COM。

     

    如果您在一个 STA 中创建 COM 对象线程,您不能的接口指针传递给另一个 STA 线程和调用签出该指针上。 由于对 STA 对象的调用应该要序列化,COM 强制这通过只允许一个线程来调用到 STA 对象 (它创建的线程)。 如果将传递给第二个 STA 线程接口指针是指向一个代理的指针,您将收到错误 0x8001010E 的 HRESULT 或 RPC_E_WRONG_THREAD (应用程序为在不同的线程调用的已封送处理的接口)。 如果接口指针是指向该对象的直接指针,COM 将不强制序列化,将不会出现上述错误,并将成为在接口方法调用。 但是,这是客户端的仍非法的行为。

     

    可以仍然调用方法在 STA 对象上从另一个 STA 线程,只要您通过代理执行它。 代理服务器是接口的您获得通过封送处理 / 拆封的副本。当您打通过代理服务器,COM 使一个线程切换和调用结束在其中创建了 STA 对象在线程的上下文中执行。

     

    there are three ways to marshal / unmarshal to another STA thread interface: 1.CoMarshalInterThreadInterfaceInStream() 和 CoGetInterfaceAndReleaseStream() : 使用此方法只有一个缺点是该接口只能取消封送一次。就是,如果从多个 STA 线程需要访问同一对象,此方法将不起作用。2.CoMarshalInterface() 和 CoUnMarshalInterface() : 这种方法是更加灵活,因为您可以一次封送接口和 unmarshal 接口很多时候您喜欢 ; 例如,封送该接口时指定 MSHLFLGS_TABLEWEAK 或 MSHLFLGS_TABLESTRONG。但它还要求更多的代码,因为您有可以创建 IStream、 设置查找指针和清理通过 CoReleaseMarshalData() 封送数据包。封送处理指向一个代理时,您必须有 Windows NT 4.0 Service Pack 4 或更高版本,Windows 98 或 Windows 95 与 DCOM 1.2 安装或更高版本。 此外使用 MSHLFLGS_TABLESTRONG 标记时,您必须安装了 Windows 2000 或更高版本。3.global Interface Table(GIT) : The GIT is that allows to store interface in one STA thread and get access to 's proxy in another STA thread COM object. this is only with Windows NT 4.0 Service Pack 3 or later,Windows 98 or Windows 95 with DCOM 1.1 available or later installed。

    最新回复(0)