Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14497972
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 20:58:50

下载本文示例代码
  在多线程程序中使用COM对象真是件令人头疼的事情。当你能够访问一个接口指针的时候,并不意味着你可以调用接口上的方法。我从来没真正搞懂过所谓COM的几种线程模式。问题是,当我试图在一个线程里调用一个COM接口的方法,而这个COM接口是在另一个线程中创建时,从来没有成功过。更糟的是,连错误提示都没有。  用全局接口表实现COM接口在不同线程中的传递  在多个线程中传递接口需要额外的工作,各种书籍上都介绍了所谓Marshal一个接口方法,不过我从来没有使用过。因为有更简单的方法,就是用全局接口表(GlobalInterfaceTable)。  GlobalInterfaceTable允许你在任何地方访问任何线程中创建的COM接口。GlobalInterfaceTable本身是一个COM对象,它实现了IGlobalInterfaceTable接口。这个接口有三个方法,分别用来注册接口,取得接口和注销接口。下面的例子介绍了GlobalInterfaceTable的基本使用方法。  首先当创建一个需要在其他线程使用的COM接口时,把它注册到GlobalInterfaceTable。 CComPtr spMyInterface;spMyInterface.CoCreateInstance();//register interface in global interface tableCComPtr spGIT;spGIT.CoCreateInstance(CLSID_StdGlobalInterfaceTable);if (spGIT){ spGIT->RegisterInterfaceInGlobal(spMyInterface, IID_IMyInterface, &m_dwCookie);}  注册时会返回一个Cookie,记住这个Cookie,并在任何线程需要使用前面接口时,通过这个Cookie获得接口。 CComPtr spMyInterface;if (m_dwCookie!=0){ CComPtr spGIT; spGIT.CoCreateInstance(CLSID_StdGlobalInterfaceTable); if (spGIT) {  spGIT->GetInterfaceFromGlobal(m_dwCookie, IID_IMyInterface, (void**)&spMyInterface.p); }}if (spMyInterface){ //Call my interface}  最后,作为一个负责任的程序员,关闭之前一定要注销前面注册的接口。 if (m_dwCookie!=0){ CComPtr spGIT; spGIT.CoCreateInstance(CLSID_StdGlobalInterfaceTable); if (spGIT) {  spGIT->RevokeInterfaceFromGlobal(m_dwCookie);  m_dwCookie = 0; }}  需要注意的时,我们每次都是新创建GlobalInterfaceTable的实例,因为它本身也是COM对象,它的指针不能在不同线程间传递。共2页。 1 2 8 :   在多线程程序中使用COM对象真是件令人头疼的事情。当你能够访问一个接口指针的时候,并不意味着你可以调用接口上的方法。我从来没真正搞懂过所谓COM的几种线程模式。问题是,当我试图在一个线程里调用一个COM接口的方法,而这个COM接口是在另一个线程中创建时,从来没有成功过。更糟的是,连错误提示都没有。  用全局接口表实现COM接口在不同线程中的传递  在多个线程中传递接口需要额外的工作,各种书籍上都介绍了所谓Marshal一个接口方法,不过我从来没有使用过。因为有更简单的方法,就是用全局接口表(GlobalInterfaceTable)。  GlobalInterfaceTable允许你在任何地方访问任何线程中创建的COM接口。GlobalInterfaceTable本身是一个COM对象,它实现了IGlobalInterfaceTable接口。这个接口有三个方法,分别用来注册接口,取得接口和注销接口。下面的例子介绍了GlobalInterfaceTable的基本使用方法。  首先当创建一个需要在其他线程使用的COM接口时,把它注册到GlobalInterfaceTable。 CComPtr spMyInterface;spMyInterface.CoCreateInstance();//register interface in global interface tableCComPtr spGIT;spGIT.CoCreateInstance(CLSID_StdGlobalInterfaceTable);if (spGIT){ spGIT->RegisterInterfaceInGlobal(spMyInterface, IID_IMyInterface, &m_dwCookie);}  注册时会返回一个Cookie,记住这个Cookie,并在任何线程需要使用前面接口时,通过这个Cookie获得接口。 CComPtr spMyInterface;if (m_dwCookie!=0){ CComPtr spGIT; spGIT.CoCreateInstance(CLSID_StdGlobalInterfaceTable); if (spGIT) {  spGIT->GetInterfaceFromGlobal(m_dwCookie, IID_IMyInterface, (void**)&spMyInterface.p); }}if (spMyInterface){ //Call my interface}  最后,作为一个负责任的程序员,关闭之前一定要注销前面注册的接口。 if (m_dwCookie!=0){ CComPtr spGIT; spGIT.CoCreateInstance(CLSID_StdGlobalInterfaceTable); if (spGIT) {  spGIT->RevokeInterfaceFromGlobal(m_dwCookie);  m_dwCookie = 0; }}  需要注意的时,我们每次都是新创建GlobalInterfaceTable的实例,因为它本身也是COM对象,它的指针不能在不同线程间传递。共2页。 1 2 8 : 下载本文示例代码


COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则COM接口在不同线程中的传递技巧两则
阅读(177) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~