ATLCOMC++/CLIVisual Studio .NET 2003Visual Studio 2008Visual Studio 2005Visual Studio 2010中级开发Visual StudioWindowsC++.NET
全局接口表:边址接口指针的简便方法
在线程之间边址接口指针的简便方法!
引言
组件对象模型 (COM) 和 ActiveX 模板库 (ATL) 是 Windows 编程中最棘手的领域,但作为 Windows 程序员,您每天都会遇到这些问题,并且很少会遇到在多线程环境中从另一个线程访问在一个线程中创建的 COM 指针的困难。 COM/ATL 具有编组的概念,并使用全局接口表来解决此问题。
在这里,我将演示如何通过一些快速代码将接口指针从一个线程封送到另一个工作线程。 ATL 提供了名为 IGlobalInterfaceTable
的接口和名为 CComGITPtr
的 COM 模板类,以帮助程序员轻松理解这个概念。
在我的示例中,我有一个带有接口 IIGitTest
的 COM 组件,我将在 GitClient 应用程序中对其进行封送处理。 如果您不知道如何创建 COM 组件,请参阅我的 创建 COM 组件的分步指南。
如何将接口指针从一个单元封送到另一个单元?
- 首先,我们必须创建一个公开
IIGitTest
并具有 get/set 属性名称的组件,然后创建一个基于 MFC 对话框的客户端应用程序 GitClient,该应用程序将从一个单元访问此接口到另一个单元? - 我们的组件名称是
GitInterface
。 我将使用#import
指令导入 DLL,因为我不想在导入的 tlh 和 tli 文件中使用命名空间,因此我将使用no_namespace
后缀与#import
一起使用。 也就是说,在我们的示例中 - 现在我们可以访问我们的 IIGitTest。 我们现在在类中添加成员变量,例如
- 为我们的接口分配内存,并且不要忘记在应用程序中初始化 COM 模型。
- 现在,为我们的接口指针赋予一些值。 这将帮助我们检查我们是否能够正确地封送我们的接口。
- 现在在客户端应用程序中释放我们的 GIT 代码。
- 现在创建一个线程,它将从全局接口表中获取
IIGitTest
指针。 - 现在,在新线程内初始化 COM,并检索我们通过
lpParam
参数发送的 cookie 标识。 - 现在创建
CComGITPtr
对象并将dwCookie
作为参数传递,这将指示CComGITPtr
对象搜索 GIT 并检索我们接口的接口指针。 - 现在,只需使用
CComGITPtr::CopyTO
函数将接口指针复制到我们的接口指针即可。 - 现在,检索该值。 记住步骤 5。
#import "..\\output\\GitInterface.dll" no_namespace
IIGitTestPtr m_pToInterface;
CoInitialize(NULL);
// initialize the com CLSID pclsid;
CLSIDFromString(L"GitInterface.IGitTest.1",&pclsid);
m_pToInterface.CreateInstance(pclsid);
TCHAR szValues[256];
m_edtGitValue.GetWindowText(szValues,256);
CComBSTR bstrValues(szValues);
m_pToInterface->put_Value(bstrValues);
CComGITPtr<IIGITTEST> pToGITTest(m_pToInterface);
DWORD dwGitCookie = pToGITTest.Detach();
您一定想知道这个 dwGitCookie
将做什么以及模板类是如何工作的? CComGITPtr
是一个模板包装器类,它封装了 IGlobalInterfaceTable
接口。 我们将接口指针传递给模板类 CComGITPtr
,作为回报,它返回 DWORD
cookie,这将帮助我们在全局接口表中找到我们的接口。
/// Create thread to try marshalling
CreateThread(NULL,NULL,ThreadProc,
reinterpret_cast<LPVOID>(dwGitCookie),NULL,NULL);
CoInitialize(NULL);
DWORD dwCookie = reinterpret_cast<DWORD>(lpParam);
CComGITPtr<IIGITTEST>pToGITTest(dwCookie);
IIGitTest *pToGitPtr;
pToGITTest.CopyTo(&pToGitPtr);
CComBSTR bstValue;
pToGitPtr->get_Value(&bstValue);
MessageBoxW(NULL,bstValue,L"From Git Interface",MB_OK);
结束 :)
通过这种方式,您可以将接口指针从一个线程封送到另一个线程,而无需考虑封送和其他相关技术的细节。 让我们再次回顾这个过程。
快速回顾
- 创建一个接口指针并将其附加到 GIT 模板类
- 从 GIT 对象中检索 cookie
- 在另一个线程中,使用
DWORD
cookie 在 GIT 表中查找接口 - 将对象复制到接口指针中
- 瞧,现在您可以使用您的接口,而没有任何异常 :)