首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将接口指针传递到线程?

如何将接口指针传递到线程?
EN

Stack Overflow用户
提问于 2009-02-04 10:20:13
回答 3查看 4.8K关注 0票数 6

注:

  • 使用raw Win32 CreateTheard() API
  • 无MFC
  • 接口只是指向vtable的指针。

问题:

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

Illustration:

代码语言:javascript
复制
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

问候

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-02-04 10:23:39

如下所述,在不安全的线程之间传递一个COM接口指针。

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

代码语言:javascript
复制
hThread = CreateThread(
                NULL,
                        0,
                        SecondaryThread,
                        (LPVOID) pis8
                        0,
                        &dwGenericThreadID);

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

线程安全版本:

代码语言:javascript
复制
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();
}
票数 8
EN

Stack Overflow用户

发布于 2009-02-04 13:58:51

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

COM对象通常是通过使用IMarshal的特殊实现来实现的。最简单的方法是聚合免费线程封送处理程序。

一些有用的联系..。

  • CoMarshalInterThreadInterfaceInStream
  • GlobalInterfaceTable (GIT)
  • CoCreateFreeThreadedMarshaler

更新:关于免费线程编组器.

从关于这个话题的评论中可以清楚地看到,有些人会建议你永远不要碰FTM。虽然“有效的COM”是一本很好的书,但我认为它的一些建议是可以解释的。第33条说“小心FTM”,而不是说“永远不要使用FTM”。它非常明智地建议谨慎,特别是当您的公寓-敏捷对象持有对其他对象的引用时,因为它们可能不是公寓-敏捷。因此,真正的建议是:在构建公寓-敏捷对象时要仔细考虑,不管它们是否使用FTM来实现它们的敏捷性。如果您确信您可以构建一个公寓式敏捷对象,我看不出您为什么不使用FTM来实现这一点。

票数 7
EN

Stack Overflow用户

发布于 2009-02-04 14:25:20

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

  • CoMashalInterThreadInterfaceInStream ==>你可以得到一个IStream接口。
  • 将该IStream传递给线程,例如,Quassnoi说。
  • 在SecondaryThread中,调用CoGetInterfaceAndReleaseStream获取接口(如有必要则调用接口的代理)。

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

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

  • 接口为IDispatch,或者为接口注册代理/存根组件。
  • 创建组件的线程具有消息循环并处理消息。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/510788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档