笔记:

  • 使用 原始 Win32 创建Theard() API
  • 无 MFC
  • 接口只是指向 vtable 的指针

问题:

  • 如何将接口指针传递给线程?

插图:

IS8Simulation *pis8 = NULL;

...

CoCreateInstance(
                 clsid,
                 NULL,
                 CLSCTX_LOCAL_SERVER,
                 __uuidof(IS8Simulation),
                 (void **) &pis8);



...

hThread = CreateThread(
                NULL,
                0,
                SecondaryThread,
                //interface pointer pis8
                0,
                &dwGenericThreadID);

...

DWORD WINAPI SecondaryThread(LPVOID iValue)
{
    //using iValue accordingly
    //E.g.: iValue->Open

问候

有帮助吗?

解决方案

如下所述,通过 COM 线程之间的接口指针不安全。

假设您知道自己在做什么:

hThread = CreateThread(
                NULL,
                        0,
                        SecondaryThread,
                        (LPVOID) pis8
                        0,
                        &dwGenericThreadID);

DWORD WINAPI SecondaryThread(LPVOID iValue)
{
   ((IS8Simulation*) iValue)->Open();
}

线程安全版本:

void MainThread()
{
    IStream* psis8;
    HRESULT res = CoMarshalInterThreadInterfaceInStream (IID_IS8SIMULATION, pis8, &psis8);
    if (FAILED(res))
         return;
    hThread = CreateThread(
                NULL,
                0,
                SecondaryThread,
                (LPVOID) psis8
                0,
                &dwGenericThreadID
          );
}

DWORD WINAPI SecondaryThread(LPVOID iValue)
{
   IS8Simulation* pis8;
   HRESULT res = CoGetInterfaceAndReleaseStream((IStream*) iValue, IID_IS8SIMULATION, &pis8);
   if (FAILED(res))
      return (DWORD) res;
   pis8->Open();
}

其他提示

如果您问题中的接口是 COM 接口,Quassnoi 给出的方法可能不够。您必须注意所使用的 COM 对象的线程模型。如果辅助线程将加入一个独立于创建 COM 对象的 COM 单元,并且该对象不是 敏捷公寓, ,您需要封送该接口指针,以便辅助线程获得代理,而不是指向对象的直接指针。

COM 对象通常通过使用 IMarshal 的特殊实现来实现单元敏捷。最简单的方法是聚合自由线程封送拆收器。

一些有用的链接...

更新:关于自由线程封送拆收器...

从该主题的评论中可以清楚地看出,有些人会建议您永远不要接触 FTM。虽然《Effective COM》是一本优秀的书,但我认为其中的一些建议值得解释。第 33 条说“当心 FTM”;它没有说“永远不要使用 FTM”。非常明智的是,它建议谨慎行事,特别是当您的公寓敏捷对象包含对其他对象的引用时,因为它们可能不是公寓敏捷的。所以真正的建议是:在构建公寓敏捷对象时要仔细考虑,无论它们是否使用 FTM 来实现敏捷性。如果您确定可以构建一个公寓敏捷对象,我认为您没有理由不使用 FTM 来实现这一目标。

您基本上需要执行以下操作:

  • CoMashalInterThreadInterfaceInStream ==> 你会得到一个 IStream 接口。
  • 将该 IStream 传递给线程,例如正如夸斯诺伊所说。
  • 在辅助线程中,调用 CoGetInterfaceAndReleaseStream 获取接口(或它的代理,如果需要)。

除非创建线程失败,否则不要释放 IStream 接口,并且在调用之前不要退出线程 CoGetInterfaceAndReleaseStream.

COM 运行时将自动为您创建代理。代理确保例如单元线程 COM 组件在创建它的线程上被调用。然而,这也要求:

  • 接口为IDispatch,或者为该接口注册了代理/存根组件
  • 创建组件的线程有一个消息循环并处理消息
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top