调试ATL组件中的引用计数问题
(hangwire发表于2002-1-16 0:33:22)
如果你怀疑自己的组件有引用计数问题,那么最好是找出导致问题的代码,而且最好是从跟踪所有AddRef() 和Release()方法调用开始,仔细检查返回的结果,找出不匹配的AddRef() 和Release()调用。
在这些方法中设置断点也是很有用的,以便程序运行到断点时,你能检查调用堆栈来判断是谁发出调用的。
为了跟踪此调用,必须在组件的类声明中插入以下的函数OuterAddRef()、 OuterRelease()、 InternalAddRef()、InternalRelease()。
class ATL_NO_VTABLE CFoo :
public CComObjectRootEx,
public CComCoClass,
public IDispatchImpl
{
public:
[...]
ULONG OuterAddRef()
{
ULONG ulReturn =
CComObjectRootEx::OuterAddRef();
ATLTRACE(_T("++++AddRef() CFoo::%p refcount = %d\n"),
this, m_dwRef);
return ulReturn;
}
ULONG OuterRelease()
{
ULONG ulReturn =
CComObjectRootEx::OuterRelease();
ATLTRACE(_T("~~~~Release() CFoo::%p refcount = %d\n"),
this, m_dwRef);
return ulReturn;
}
ULONG InternalAddRef()
{
ULONG ulReturn =
CComObjectRootEx::InternalAddRef();
ATLTRACE(_T("++++AddRef() CFoo::%p refcount = %d\n"),
this, m_dwRef);
return ulReturn;
}
ULONG InternalRelease()
{
ULONG ulReturn =
CComObjectRootEx::InternalRelease();
ATLTRACE(_T("~~~~Release() CFoo::%p refcount = %d\n"),
this, m_dwRef);
return ulReturn;
}
…
};
这些方法会改写ATL中CComObjectRootEx相应的方法。当你的组件被聚合时,ATL调用这些方法的"外部(outer)"版本,、否则调用"内部(internal)"版本。在DevStudio的调试环境输出窗口中显示如下信息:
++++AddRef() CFoo::04540600 refcount = 1
++++AddRef() CFoo::04540600 refcount = 2
~~~~Release() CFoo::04540600 refcount = 1
++++AddRef() CFoo::04540600 refcount = 2
++++AddRef() CFoo::04540600 refcount = 3
~~~~Release() CFoo::04540600 refcount = 2
~~~~Release() CFoo::04540600 refcount = 1
~~~~Release() CFoo::04540600 refcount = 0
注意:在类名之后显示的对象"this"指针值可以帮你区分相同的类中不同的对象。