com组件的析构函数不调用

war3gu 2008-07-05 03:45:29
我写了一个com组件,继承关系如下
class ATL_NO_VTABLE CChatRoom :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CChatRoom, &CLSID_ChatRoom>,
public IConnectionPointContainerImpl<CChatRoom>,
public CProxy_IChatRoomEvents<CChatRoom>,
public IDispatchImpl<IChatRoom, &IID_IChatRoom, &LIBID_ATLBROWSERLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,

public CWindowImpl<CChatRoom,CWindow,CMyControlWinTraits>,

public IOleClientSite,
public IOleInPlaceSite,
public IDocHostUIHandler,
public IDocHostShowUI
组件有个窗口,窗口里嵌入ie浏览器组件。然后我在程序中创建上面的组件,组件的一切运行都正常,用断点跟踪,构造函数,finnalconstractor都能调用,但是组件的析构函数和finalrelease却调用不到。组件指针保留在std::map<std::string,CComPtr<IChatRoom> >中,我调用map的erase或者关闭窗口都无法触发析构函数或finalrelease,真是太奇怪了。请牛人指点一下,先谢谢了。
...全文
205 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
jixingzhong 2008-07-08
  • 打赏
  • 举报
回复
智能指针,调用release方法就是了··

finalrelease调用不到的最大可能就是引用计数未清零,也就是尚有未释放的引用
jameshooo 2008-07-08
  • 打赏
  • 举报
回复
智能指针不能直接访问addref,可以使用成员,比如 smartpt.p->AddRef()/smartpt.p->Release()
war3gu 2008-07-07
  • 打赏
  • 举报
回复

CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> m_spWebBrowser;
CComQIPtr<IOleInPlaceObject, &IID_IOleInPlaceObject> m_spInPlaceObject;
CComPtr<IOleObject> spOleObject;

void Run()
{
HRESULT hr = CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_INPROC, IID_IOleObject,
(void**)&spOleObject);
if (spOleObject->SetClientSite( static_cast<IOleClientSite*>(this) ) != S_OK)//这儿要对指针进行引用
{
ThMessageBox(NULL,_T("SetClientSite failed"),"出错",MB_OK);
return E_FAIL;
}
MSG msg;
GetClientRect(&rcClient);
//激活IE控件
hr = spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, &msg, this, 0, m_hWnd, &rcClient);//这儿要对指针进行引用
if (hr != S_OK)
{
ThMessageBox(NULL,_T("DoVerb failed"),"出错",MB_OK);
return E_FAIL;
}
m_spWebBrowser = spOleObject;
if (!m_spWebBrowser)
return E_FAIL;
hr = AtlAdvise(m_spWebBrowser, GetUnknown(), DIID_DWebBrowserEvents2, &m_dwCookie);//这儿要对指针进行引用
if (FAILED(hr))
ATLTRACE(_T("Failed to Advise\n"));
m_spInPlaceObject = m_spWebBrowser;
_ASSERT(m_spInPlaceObject);
if (m_spInPlaceObject)
m_spInPlaceObject->SetObjectRects(&rcClient, &rcClient);
}
上面就是主要代码,我发现除了我自己对CChatRoom组件进行引用外,ie组件也对这个组件进行引用。SetClientSite DoVerb 和AtlAdvise中执行了引用操作,其中AtlUnadvise是AtlAdvise的反操作,那么怎么对另外2个函数解除引用呢。

另外:
SetClientSite可以正常进入。
addref和release全是私有函数,根本没法调用。
jameshooo 2008-07-05
  • 打赏
  • 举报
回复
引用计数的维护有问题,组件找不到机会释放自己。可以使用IChatRoom::AddRef看看返回的引用计数是多少
vocanicy 2008-07-05
  • 打赏
  • 举报
回复
问题应该不是出在你的数组这里,你的数组里使用CComPtr会自动调用Release的

我想应该是在你放入数组之前的接口指针忘了调用Release,导致对象的引用计数不为零,所以没有调用FinalRelease
liyinlei 2008-07-05
  • 打赏
  • 举报
回复
对组件指针还需调用release啊。
yjgx007 2008-07-05
  • 打赏
  • 举报
回复
SetClientSite能进入吗?

3,248

社区成员

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

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