65.9K
CodeProject 正在变化。 阅读更多。
Home

全局接口表:边址接口指针的简便方法

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.65/5 (12投票s)

2007年3月1日

CPOL

3分钟阅读

viewsIcon

82733

downloadIcon

605

在线程之间边址接口指针的简便方法!

引言

组件对象模型 (COM) 和 ActiveX 模板库 (ATL) 是 Windows 编程中最棘手的领域,但作为 Windows 程序员,您每天都会遇到这些问题,并且很少会遇到在多线程环境中从另一个线程访问在一个线程中创建的 COM 指针的困难。 COM/ATL 具有编组的概念,并使用全局接口表来解决此问题。

在这里,我将演示如何通过一些快速代码将接口指针从一个线程封送到另一个工作线程。 ATL 提供了名为 IGlobalInterfaceTable 的接口和名为 CComGITPtr 的 COM 模板类,以帮助程序员轻松理解这个概念。

在我的示例中,我有一个带有接口 IIGitTest 的 COM 组件,我将在 GitClient 应用程序中对其进行封送处理。 如果您不知道如何创建 COM 组件,请参阅我的 创建 COM 组件的分步指南

如何将接口指针从一个单元封送到另一个单元?

  1. 首先,我们必须创建一个公开 IIGitTest 并具有 get/set 属性名称的组件,然后创建一个基于 MFC 对话框的客户端应用程序 GitClient,该应用程序将从一个单元访问此接口到另一个单元?
  2. 我们的组件名称是 GitInterface。 我将使用 #import 指令导入 DLL,因为我不想在导入的 tlhtli 文件中使用命名空间,因此我将使用 no_namespace 后缀与 #import 一起使用。 也就是说,在我们的示例中
  3.  #import "..\\output\\GitInterface.dll" no_namespace 
  4. 现在我们可以访问我们的 IIGitTest。 我们现在在类中添加成员变量,例如
  5. IIGitTestPtr m_pToInterface;
  6. 为我们的接口分配内存,并且不要忘记在应用程序中初始化 COM 模型。
  7. CoInitialize(NULL);
    // initialize the com CLSID pclsid;
    CLSIDFromString(L"GitInterface.IGitTest.1",&pclsid);
    m_pToInterface.CreateInstance(pclsid);
  8. 现在,为我们的接口指针赋予一些值。 这将帮助我们检查我们是否能够正确地封送我们的接口。
  9. TCHAR szValues[256]; 
    m_edtGitValue.GetWindowText(szValues,256); 
    CComBSTR bstrValues(szValues); 
    m_pToInterface->put_Value(bstrValues);
  10. 现在在客户端应用程序中释放我们的 GIT 代码。
  11. CComGITPtr<IIGITTEST> pToGITTest(m_pToInterface);
    DWORD dwGitCookie = pToGITTest.Detach();

    您一定想知道这个 dwGitCookie 将做什么以及模板类是如何工作的? CComGITPtr 是一个模板包装器类,它封装了 IGlobalInterfaceTable 接口。 我们将接口指针传递给模板类 CComGITPtr,作为回报,它返回 DWORD cookie,这将帮助我们在全局接口表中找到我们的接口。

  12. 现在创建一个线程,它将从全局接口表中获取 IIGitTest 指针。
  13. /// Create thread to try marshalling 
    CreateThread(NULL,NULL,ThreadProc, 
       reinterpret_cast<LPVOID>(dwGitCookie),NULL,NULL);
  14. 现在,在新线程内初始化 COM,并检索我们通过 lpParam 参数发送的 cookie 标识。
  15. CoInitialize(NULL);
    DWORD dwCookie = reinterpret_cast<DWORD>(lpParam);
  16. 现在创建 CComGITPtr 对象并将 dwCookie 作为参数传递,这将指示 CComGITPtr 对象搜索 GIT 并检索我们接口的接口指针。
  17. CComGITPtr<IIGITTEST>pToGITTest(dwCookie);
  18. 现在,只需使用 CComGITPtr::CopyTO 函数将接口指针复制到我们的接口指针即可。
  19. IIGitTest *pToGitPtr;
    pToGITTest.CopyTo(&pToGitPtr);
  20. 现在,检索该值。 记住步骤 5。
  21. CComBSTR bstValue; 
    pToGitPtr->get_Value(&bstValue); 
    MessageBoxW(NULL,bstValue,L"From Git Interface",MB_OK);

    结束 :)

通过这种方式,您可以将接口指针从一个线程封送到另一个线程,而无需考虑封送和其他相关技术的细节。 让我们再次回顾这个过程。

快速回顾

  1. 创建一个接口指针并将其附加到 GIT 模板类
  2. 从 GIT 对象中检索 cookie
  3. 在另一个线程中,使用 DWORD cookie 在 GIT 表中查找接口
  4. 将对象复制到接口指针中
  5. 瞧,现在您可以使用您的接口,而没有任何异常 :)

参考

  1. 何时使用全局接口表
  2. CComGITPtr 类
© . All rights reserved.