ATL Internals 2ed复习.chapter 4.Debugging

ASSERT

#ifndef ATLASSERT                     
#define ATLASSERT(expr) _ASSERTE(expr)
#endif                                


上述这个宏依赖CRT

传输到debug output

inline void _cdecl AtlTrace(LPCSTR pszFormat, ...) 
inline void _cdecl AtlTrace(LPCWSTR pszFormat, ...)

例子:

HRESULT CPenguin::FinalConstruct() {
  ATLTRACE(__TEXT("%d+%d= %d\n"), 2, 2, 2+2);
}


还可以提示级别:

void AtlTrace2(DWORD_PTR dwCategory, UINT nLevel,
    LPCSTR pszFormat, ...)                       
void AtlTrace2(DWORD_PTR dwCategory, UINT nLevel,
    LPCWSTR pszFormat, ...)                      


在ATL内部已经制定了一套Category

#ifdef _DEBUG                                                   
#define DECLARE_TRACE_CATEGORY( name ) \                        
    extern ATL::CTraceCategory name;                            
#else                                                           
#define DECLARE_TRACE_CATEGORY( name ) const DWORD_PTR name = 0;
#endif                                                          
                                                                
DECLARE_TRACE_CATEGORY( atlTraceGeneral )                       
DECLARE_TRACE_CATEGORY( atlTraceCOM )                           
DECLARE_TRACE_CATEGORY( atlTraceQI )                            
DECLARE_TRACE_CATEGORY( atlTraceRegistrar )                     
DECLARE_TRACE_CATEGORY( atlTraceRefcount )                      
DECLARE_TRACE_CATEGORY( atlTraceWindowing )                     
DECLARE_TRACE_CATEGORY( atlTraceControls )                      
DECLARE_TRACE_CATEGORY( atlTraceHosting )                       
DECLARE_TRACE_CATEGORY( atlTraceDBClient )                      
DECLARE_TRACE_CATEGORY( atlTraceDBProvider )                    
DECLARE_TRACE_CATEGORY( atlTraceSnapin )                        
DECLARE_TRACE_CATEGORY( atlTraceNotImpl )                       
DECLARE_TRACE_CATEGORY( atlTraceAllocation )                    
DECLARE_TRACE_CATEGORY( atlTraceException )                     
DECLARE_TRACE_CATEGORY( atlTraceTime )                          
DECLARE_TRACE_CATEGORY( atlTraceCache )                         
DECLARE_TRACE_CATEGORY( atlTraceStencil )                       
DECLARE_TRACE_CATEGORY( atlTraceString )                        
DECLARE_TRACE_CATEGORY( atlTraceMap )                           
DECLARE_TRACE_CATEGORY( atlTraceUtil )                          
DECLARE_TRACE_CATEGORY( atlTraceSecurity )                      
DECLARE_TRACE_CATEGORY( atlTraceSync )                          
DECLARE_TRACE_CATEGORY( atlTraceISAPI )                         
                                                                
// atlTraceUser categories are no longer needed.                
// Just declare your own trace category using CTraceCategory.   
DECLARE_TRACE_CATEGORY( atlTraceUser )                          
DECLARE_TRACE_CATEGORY( atlTraceUser2 )                         
DECLARE_TRACE_CATEGORY( atlTraceUser3 )                         
DECLARE_TRACE_CATEGORY( atlTraceUser4 )                         
                                                                
#pragma deprecated( atlTraceUser )                              
#pragma deprecated( atlTraceUser2 )                             
#pragma deprecated( atlTraceUser3 )                             
#pragma deprecated( atlTraceUser4 )                             


用户可以这样使用:

CTraceCategory PenguinTraces( "CPenguin trace", 1 );
...
STDMETHODIMP CPenguin::Fly() {
    ATLTRACE2(PenguinTraces,   2,
        _T("IBird::Fly\n"));
    ATLTRACE2(PenguinTraces,   42,
        _T("Hmmm... Penguins can't fly...\n"));
    ATLTRACE2(atlTraceNotImpl, 0,
        _T("IBird::Fly not implemented!\n"));
    return E_NOTIMPL;
}


当然还有更简便的方法,因为ATL已经有了:

#define ATLTRACENOTIMPL(funcname) \               
  ATLTRACE2(atlTraceNotImpl, 2, \                 
    _T("ATL: %s not implemented.\n"), funcname); \
  return E_NOTIMPL                                

所以:

STDMETHOD(SetMoniker)(DWORD, IMoniker*) {             
    ATLTRACENOTIMPL(_T("IOleObjectImpl::SetMoniker"));
}                                                     


Tracing Calls to QueryInterface

在编译时指定_ATL_DEBUG_QI,则可以跟踪QueryInterface

Tracing Calls to AddRef and Release

在编译时指定_ATL_DEBUG_INTERFACES,则可以跟踪QueryInterface,AddRef,Release,并且可以检验是否有LEAK

使用_AtlDebugInterfacesModule可以指定break,例如:

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason,
    LPVOID lpReserved) {
    hInstance;
    BOOL b = _AtlModule.DllMain(dwReason, lpReserved);
    // Trace down interface leaks
#ifdef _ATL_DEBUG_INTERFACES
    _AtlDebugInterfacesModule.m_nIndexBreakAt = 4;
#endif
    return b;
}

_ATL_DEBUG_REFCOUNT

对于ATL3之前的版本,等效于_ATL_DEBUG_INTERFACES

 



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值