リリース モードで TRACE マクロを有効にするにはどうすればよいですか?
質問
の トレースマクロ コードがコンパイルされるときに、デバッガーに診断メッセージを出力するために使用できます。 デバッグ モード。にいる間も同じメッセージが必要です リリース モード。これを達成する方法はありますか?
(してください ない リリース モードで TRACE を使用すべきではない理由を議論するのは時間を無駄にします :-)
解決
実際、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);
}
他のヒント
数年前、私は同様の機能が必要だったので、次のコードをまとめました。ファイルに保存するだけです。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
それは私が見た最も単純なコードです
#undef ATLTRACE
#undef ATLTRACE2
#define ATLTRACE2 CAtlTrace(__FILE__, __LINE__, __FUNCTION__)
#define ATLTRACE ATLTRACE2
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.
}
所属していません StackOverflow