请教,关于多线程激发事件时,造成的内存泄漏问题,100分诚赠。

qscj 2003-08-22 06:29:09
*概要
  ATL的封装函数IConnectionPointImplMT<T, piid, CDV>::GetInterfaceAt(int nConnectionIndex)在其内部调用IGlobalInterfaceTable::GetInterfaceFromGlobal(DWORD dwCookie, REFIID riid,void **ppv)时发生内存泄漏,原ATL封装函数如下:

template <class T, const IID* piid, class CDV>
LPUNKNOWN IConnectionPointImplMT<T, piid, CDV>::GetInterfaceAt(
int nConnectionIndex)
{
m_CPMTCritSec.Lock();

LPUNKNOWN pUnk = NULL;
// IConnectionPointImplMT Vector stores DWORDs instead of IUnknown pointers,
// explicit cast required:
DWORD dwGITCookie = (DWORD)(m_vec.GetAt(nConnectionIndex));
if (dwGITCookie != NULL)
{
IID iid;
GetConnectionInterface(&iid);
//HRESULT hr = S_OK;
/*!*/ HRESULT hr = m_pGIT->GetInterfaceFromGlobal( // <- 就是这条!!
dwGITCookie, iid, reinterpret_cast<void **>(&pUnk));
ATLASSERT(hr == S_OK);
}

m_CPMTCritSec.Unlock();

return pUnk;
}

*我实在找不到解决方法
  我想当然:既然GetInterfaceFromGlobal()申请了资源,必然有一个对应的函数可以释放掉,但我仔细阅读过MSDN,也都仔细试过,三个函数没有一个能实现:IGlobalInterfaceTable::GetInterfaceFromGlobal()
IGlobalInterfaceTable::RegisterInterfaceInGlobal()
IGlobalInterfaceTable::RevokeInterfaceFromGlobal()


*我也全都按照微软网站上的方法做了

class CProxy_IEvntFirerEvents : public IConnectionPointImpl<T, &DIID__IEvntFirerEvents, CComDynamicUnkArray>
换成
class CProxy_IEvntFirerEvents : public IConnectionPointImplMT<T, &DIID__IEvntFirerEvents, CComDynamicUnkArray>


pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
换成
CComPtr<IUnknown> sp;
sp.Attach (GetInterfaceAt(nConnectionIndex));

我也试了其它的释放方法,要么行不通,要么无效。

请各位高手帮我,谢谢!

...全文
146 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
qscj 2003-08-27
  • 打赏
  • 举报
回复
我先结帖,以后再同大家讨论,谢谢各位的帮助。
Analyst 2003-08-26
  • 打赏
  • 举报
回复
vb的事件接收对象不可能是Free或Both的,检查内存泄露最好还是用bounds check去查
这里有一篇在多线程中激发事件的文章:http://www.codeguru.com/atl/ThreadEvents.shtml
你可以去参考一下。
ShyWJB 2003-08-26
  • 打赏
  • 举报
回复

学习,up
dir1 2003-08-26
  • 打赏
  • 举报
回复
哎,我估计到你是用Apartment,:(
你用Free试试,用Both也可以
用wizard重新生成框架再把代码copy过去试试。
你可以看看COM的线程管理。
good luck,:)
dir1 2003-08-26
  • 打赏
  • 举报
回复
哎,我估计到你是用Apartment,:(
你用Free试试,用Both也可以
用wizard重新生成框架再把代码copy过去试试。
你可以看看COM的线程管理。
good luck,:)
qscj 2003-08-26
  • 打赏
  • 举报
回复
Analyst()你好,

我已经试过了把工程中所有CoInitializeEx换成CoInitialize,不行 :( 不是这个原因
不过还是谢谢你!
qscj 2003-08-26
  • 打赏
  • 举报
回复
Up

各位可怜可怜我吧,我就要掉信誉值了。

:(
qscj 2003-08-26
  • 打赏
  • 举报
回复
bravebarbarian(野蛮人)你好,

  “apn部门” <- 这个名词我没有见过,我是个VC程序员,目前的工作是做组件,给VB们用,因为数据库操作归他们。
  我用惯了VC,不喜欢VB。



dir1(Aikoc)你好,

我用的是Apartment,我用得对吗?请指教。
VCP4 2003-08-26
  • 打赏
  • 举报
回复
用多线程就是容易多问题出现。
Analyst 2003-08-26
  • 打赏
  • 举报
回复
CoInitializeEx(NULL,COINIT_MULTITHREADED)是用来创建自由线程套间的,和你的组件线程模型不符,应该用CoInitialize(NULL).

SnHnBn 2003-08-26
  • 打赏
  • 举报
回复
无济于事也要调用m_pGIT->Release(),可能你的问题是多种原因引起的。你先按照正确的调用进行,再找其他原因。
qscj 2003-08-26
  • 打赏
  • 举报
回复
SnHnBn(大可达)你好

我在GetInterfaceFromGlobal()之后紧接着就调用了pUnk->Release();和m_pGIT->Release()然后再pUnk = NULL,就这都无济于事 :( 不是Release的问题



lifezhu(来福) 你好

CoUnInitialize我特别注意调用它,不是它的问题


请问为什么不要调用::CoInitializeEx(NULL,COINIT_MULTITHREADED)?我确实是调用了它

lifezhu 2003-08-26
  • 打赏
  • 举报
回复
作为多进程的GlobalTable如果不对每个线程调用::CoUnInitialize(),就会导致列集信息无法释放,建议不要实用::CoInitializeEx(NULL,COINIT_MULTITHREADED)
SnHnBn 2003-08-26
  • 打赏
  • 举报
回复
m_pGIT->Release()应该和m_pGIT->GetInterfaceFromGlobal匹配,你在什么地方Release的?次数是否一样?
qscj 2003-08-25
  • 打赏
  • 举报
回复
chouchou()你好

请给我“MS中有关于COM对象内部多线程引发客户端事件的方法”
我急用,谢谢

yazjh@yahoo.com.cn
dir1 2003-08-25
  • 打赏
  • 举报
回复
我估计这个问题是线程调度问题。
不知道你用的是什么管理方式Free,Both?
你可以试一试自己调度
CoMarshalInterThreadInterfaceInStream
CoGetInterfaceAndReleaseStream
bravebarbarian 2003-08-25
  • 打赏
  • 举报
回复
看来不是,怎么会用vb?
bravebarbarian 2003-08-25
  • 打赏
  • 举报
回复
你是apn部门的不。哪个组的
qscj 2003-08-24
  • 打赏
  • 举报
回复
Up
qscj 2003-08-24
  • 打赏
  • 举报
回复
arxing(阿行)你好,

不好意思,我已经试过m_pGIT->Release()和pUnk->Release()了,不对呀...

引用循环我也已经试过了,IConnectionPointImplMT<T, piid, CDV>::GetInterfaceAt()在激发1次事件时只调用了1次。

:(

不过还是得多谢你的帮助。



加载更多回复(17)

3,245

社区成员

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

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