问个线程间调用同一组件的问题

husky2006 2008-04-16 06:24:01
生成一个静态对象,多个线程都可以调用该对象。该静态对象创建一个进程外组件。下面举个例子
线程1,首先创建静态对象StaticObject,该对象会创建一个进程外组件ComA,调用ComA的所有方法都成功。
线程2,得到该静态对象StaticObject,然后用该对象中已经创建的组件ComA去调用ComA的方法,但是所有方法都调用失败。
有人知道为什么吗?
检查两次调用所有的指针都是一样的,但是就是线程2就是无法调用ComA的方法,有人知道为什么吗?
...全文
186 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
scq2099yt 2008-04-17
  • 打赏
  • 举报
回复
up
husky2006 2008-04-16
  • 打赏
  • 举报
回复
我记得Free不管套间里面的线程同步,而department却会管,会不会有问题?多谢!
husky2006 2008-04-16
  • 打赏
  • 举报
回复
多谢指点,我们的项目现在不能这么用,无法共同使用cookie。项目里有过类似的组件,可以多线程调用成功,我的却不行。是不是和用VC创建atlobject时选择的属性有关?我选择的是Free,是不是应该选department?
Kudeet 2008-04-16
  • 打赏
  • 举报
回复
也可以用CoMarshalInterThreadInterfaceInStream和CoGetInterfaceAndReleaseStream
Kudeet 2008-04-16
  • 打赏
  • 举报
回复
线程1,首先创建静态对象StaticObject,该对象会创建一个进程外组件ComA,调用ComA的所有方法都成功。
===>表示COMA的接口属于线程1
线程2,得到该静态对象StaticObject,然后用该对象中已经创建的组件ComA去调用ComA的方法,但是所有方法都调用失败。
===>这样就表示通过线程2访问线程1在COMA方法


方法1:用GAT表解决跨线程传递COM接口

首先当创建一个需要在其他线程使用的COM接口时,把它注册到GlobalInterfaceTable

CComPtr<IMyInterface> spMyInterface;
spMyInterface.CoCreateInstance();
//register interface in global interface table
CComPtr<IGlobalInterfaceTable> spGIT;
spGIT.CoCreateInstance(CLSID_StdGlobalInterfaceTable);
if (spGIT)
{
spGIT->RegisterInterfaceInGlobal(spMyInterface, IID_IMyInterface, &m_dwCookie);
}

注册时会返回一个Cookie,记住这个Cookie,并在任何线程需要使用前面接口时,通过这个Cookie获得接口。

CComPtr<IMyInterface> spMyInterface;
if (m_dwCookie!=0)
{
CComPtr<IGlobalInterfaceTable> 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<IGlobalInterfaceTable> spGIT;
spGIT.CoCreateInstance(CLSID_StdGlobalInterfaceTable);
if (spGIT)
{
spGIT->RevokeInterfaceFromGlobal(m_dwCookie);
m_dwCookie = 0;
}
}
Kudeet 2008-04-16
  • 打赏
  • 举报
回复
原因很简单,因为COM接口不能随便跨线程传递。
晨星 2008-04-16
  • 打赏
  • 举报
回复
调用失败,返回的值有没有什么线索?
husky2006 2008-04-16
  • 打赏
  • 举报
回复
会不会和套间的线程同步有关系?
husky2006 2008-04-16
  • 打赏
  • 举报
回复
试了不行,似乎早就已经CoInitializeEx了。
cnzdgs 2008-04-16
  • 打赏
  • 举报
回复
跟对象没什么关系,每个线程要调用COM都必须先执行CoInitializeEx。
husky2006 2008-04-16
  • 打赏
  • 举报
回复
两个线程不是直接调组件,是静态对象里面调的组件
cnzdgs 2008-04-16
  • 打赏
  • 举报
回复
每个线程都需要先执行CoInitializeEx。

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧