在调试模式下编译代码时, TRACE macro 可用于向调试器输出诊断消息。在发布模式下,我需要相同的消息。有没有办法实现这个目标?
(请不浪费时间讨论为什么我不应该在发布模式下使用TRACE: - )
答案 0 :(得分:8)
实际上,TRACE宏比OutputDebugString更灵活。它采用printf()样式格式字符串和参数列表,而OutputDebugString只接受一个字符串。为了在发布模式下实现完整的TRACE功能,您需要执行以下操作:
void trace(const char* format, ...)
{
char buffer[1000];
va_list argptr;
va_start(argptr, format);
wvsprintf(buffer, format, argptr);
va_end(argptr);
OutputDebugString(buffer);
}
答案 1 :(得分:4)
几年前我需要类似的功能,所以我拼凑了以下代码。只需将其保存到文件中,例如rtrace.h,将它包含在stdafx.h的末尾,并将_RTRACE添加到预处理器定义的发布模式。
也许有人会找到它的用途: - )
约翰
#pragma once //------------------------------------------------------------------------------------------------ // // Author: John Cullen // Date: 2006/04/12 // Based On: MSDN examples for variable argument lists and ATL implementation of TRACE. // // Description: Allows the use of TRACE statements in RELEASE builds, by overriding the // TRACE macro definition and redefining in terms of the RTRACE class and overloaded // operator (). Trace output is generated by calling OutputDebugString() directly. // // // Usage: Add to the end of stdafx.h and add _RTRACE to the preprocessor defines (typically // for RELEASE builds, although the flag will be ignored for DEBUG builds. // //------------------------------------------------------------------------------------------------ #ifdef _DEBUG // NL defined as a shortcut for writing FTRACE(_T("\n")); for example, instead write FTRACE(NL); #define NL _T("\n") #define LTRACE TRACE(_T("%s(%d): "), __FILE__, __LINE__); TRACE #define FTRACE TRACE(_T("%s(%d): %s: "), __FILE__, __LINE__, __FUNCTION__); TRACE #else // _DEBUG #ifdef _RTRACE #undef TRACE #define TRACE RTRACE() #define LTRACE RTRACE(__FILE__, __LINE__) #define FTRACE RTRACE(__FILE__, __LINE__, __FUNCTION__) #define NL _T("\n") class RTRACE { public: // default constructor, no params RTRACE(void) : m_pszFileName( NULL ), m_nLineNo( 0 ), m_pszFuncName( NULL ) {}; // overloaded constructor, filename and lineno RTRACE(PCTSTR const pszFileName, int nLineNo) : m_pszFileName(pszFileName), m_nLineNo(nLineNo), m_pszFuncName(NULL) {}; // overloaded constructor, filename, lineno, and function name RTRACE(PCTSTR const pszFileName, int nLineNo, PCTSTR const pszFuncName) : m_pszFileName(pszFileName), m_nLineNo(nLineNo), m_pszFuncName(pszFuncName) {}; virtual ~RTRACE(void) {}; // no arguments passed, e.g. RTRACE()() void operator()() const { // no arguments passed, just dump the file, line and function if requested OutputFileAndLine(); OutputFunction(); } // format string and parameters passed, e.g. RTRACE()(_T("%s\n"), someStringVar) void operator()(const PTCHAR pszFmt, ...) const { // dump the file, line and function if requested, followed by the TRACE arguments OutputFileAndLine(); OutputFunction(); // perform the standard TRACE output processing va_list ptr; va_start( ptr, pszFmt ); INT len = _vsctprintf( pszFmt, ptr ) + 1; TCHAR* buffer = (PTCHAR) malloc( len * sizeof(TCHAR) ); _vstprintf( buffer, pszFmt, ptr ); OutputDebugString(buffer); free( buffer ); } private: // output the current file and line inline void OutputFileAndLine() const { if (m_pszFileName && _tcslen(m_pszFileName) > 0) { INT len = _sctprintf( _T("%s(%d): "), m_pszFileName, m_nLineNo ) + 1; PTCHAR buffer = (PTCHAR) malloc( len * sizeof(TCHAR) ); _stprintf( buffer, _T("%s(%d): "), m_pszFileName, m_nLineNo ); OutputDebugString( buffer ); free( buffer ); } } // output the current function name inline void OutputFunction() const { if (m_pszFuncName && _tcslen(m_pszFuncName) > 0) { INT len = _sctprintf( _T("%s: "), m_pszFuncName ) + 1; PTCHAR buffer = (PTCHAR) malloc( len * sizeof(TCHAR) ); _stprintf( buffer, _T("%s: "), m_pszFuncName ); OutputDebugString( buffer ); free( buffer ); } } private: PCTSTR const m_pszFuncName; PCTSTR const m_pszFileName; const int m_nLineNo; }; #endif // _RTRACE #endif // NDEBUG
答案 2 :(得分:2)
TRACE只是OutputDebugString的一个宏。因此,您可以轻松地创建自己的TRACE宏(或称之为其他内容)来调用OutputDebugString。
答案 3 :(得分:2)
这是我见过的最简单的代码
#undef ATLTRACE
#undef ATLTRACE2
#define ATLTRACE2 CAtlTrace(__FILE__, __LINE__, __FUNCTION__)
#define ATLTRACE ATLTRACE2
答案 4 :(得分:1)
在MFC中,TRACE被定义为ATLTRACE。在发布模式中定义为:
#define ATLTRACE __noop
因此,使用MFC的开箱即用TRACE,您实际上无法读取任何TRACE文本,因为它甚至不会被写出来。您可以编写自己的TRACE函数,然后重新定义TRACE宏。你可以这样做:
void MyTrace(const CString& text)
{
::OutputDebugString(text); // Outputs to console, same as regular TRACE
// TODO: Do whatever output you need here. Write to event log / write to text file / write to pipe etc.
}