15

TRACE 宏可用于在调试模式下编译代码时向调试器输出诊断消息。在发布模式下我需要相同的消息。有没有办法做到这一点?

(请不要浪费时间讨论为什么我不应该在发布模式下使用 TRACE :-)

4

5 回答 5

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);
}
于 2008-09-03T02:11:11.033 回答
4

几年前,我需要类似的功能,所以我拼凑了以下代码。只需将它保存到一个文件中,例如 rtrace.h,将它包含在 stdafx.h 的末尾,并将 _RTRACE 添加到预处理器定义的发布模式中。

也许有人会发现它的用途:-)

约翰

#pragma 一次

//------------------------------------------------ ------------------------------------------------
//
// 作者:约翰·卡伦
// 日期:2006/04/12
// 基于:变量参数列表的 MSDN 示例和 TRACE 的 ATL 实现。
//
// 描述:允许在 RELEASE 构建中使用 TRACE 语句,通过覆盖
// 根据 RTRACE 类和重载的 TRACE 宏定义和重新定义
// 操作员 ()。通过直接调用 OutputDebugString() 生成跟踪输出。
//
//
// 用法:添加到 stdafx.h 的末尾,并将 _RTRACE 添加到预处理器定义中(通常
// 对于 RELEASE 构建,尽管对于 DEBUG 构建,该标志将被忽略。
//
//------------------------------------------------ ------------------------------------------------

#ifdef _DEBUG

// NL 定义为编写 FTRACE(_T("\n")); 的快捷方式 例如,改为写 FTRACE(NL);
#define NL _T("\n")
#define LTRACE TRACE(_T("%s(%d): "), __FILE__, __LINE__); 痕迹
#define FTRACE TRACE(_T("%s(%d): %s: "), __FILE__, __LINE__, __FUNCTION__); 痕迹

#else // _DEBUG

#ifdef _RTRACE
#undef 追踪
#define TRACE RTRACE()
#define LTRACE RTRACE(__FILE__, __LINE__)
#define FTRACE RTRACE(__FILE__, __LINE__, __FUNCTION__)
#define NL _T("\n")

RTRACE 类
{
上市:
    // 默认构造函数,无参数
    RTRACE(void) : m_pszFileName( NULL ), m_nLineNo( 0 ), m_pszFuncName( NULL ) {};

    // 重载构造函数、文件名和行号
    RTRACE(PCTSTR const pszFileName,int nLineNo):
        m_pszFileName(pszFileName), m_nLineNo(nLineNo), m_pszFuncName(NULL) {};

    // 重载构造函数、文件名、行号和函数名
    RTRACE(PCTSTR const pszFileName,int nLineNo,PCTSTR const pszFuncName):
        m_pszFileName(pszFileName), m_nLineNo(nLineNo), m_pszFuncName(pszFuncName) {};

    虚拟 ~RTRACE(void) {};

    // 没有传递参数,例如 RTRACE()()
    无效运算符()()常量
    {
        // 不传递参数,如果需要,只转储文件、行和函数
        输出文件和线();
        输出函数();
    }

    // 格式化字符串和传递的参数,例如 RTRACE()(_T("%s\n"), someStringVar)
    void operator()(const PTCHAR pszFmt, ...) const
    {
        // 如果需要,转储文件、行和函数,后跟 TRACE 参数
        输出文件和线();
        输出函数();

        // 执行标准的 TRACE 输出处理
        va_list 指针;va_start(点,pszFmt);
        INT len = _vsctprintf(pszFmt, ptr) + 1;
        TCHAR* 缓冲区 = (PTCHAR) malloc( len * sizeof(TCHAR) );
        _vstprintf(缓冲区,pszFmt,ptr);
        输出调试字符串(缓冲区);
        空闲(缓冲区);
    }

私人的:
    // 输出当前文件和行
    内联 void OutputFileAndLine() 常量
    {
        如果 (m_pszFileName && _tcslen(m_pszFileName) > 0)
        {
            INT len = _sctprintf( _T("%s(%d): "), m_pszFileName, m_nLineNo ) + 1;
            PTCHAR 缓冲区 = (PTCHAR) malloc( len * sizeof(TCHAR) );
            _stprintf(缓冲区, _T("%s(%d): "), m_pszFileName, m_nLineNo );
            输出调试字符串(缓冲区);
            空闲(缓冲区);
        }
    }

    // 输出当前函数名
    内联 void OutputFunction() 常量
    {
        如果 (m_pszFuncName && _tcslen(m_pszFuncName) > 0)
        {
            INT len = _sctprintf( _T("%s: "), m_pszFuncName ) + 1;
            PTCHAR 缓冲区 = (PTCHAR) malloc( len * sizeof(TCHAR) );
            _stprintf(缓冲区, _T("%s:"), m_pszFuncName);
            输出调试字符串(缓冲区);
            空闲(缓冲区);
        }
    }

私人的:
    PCTSTR 常量 m_pszFuncName;
    PCTSTR 常量 m_pszFileName;
    const int m_nLineNo;
};

#endif // _RTRACE

#endif // NDEBUG

于 2009-04-22T14:56:25.897 回答
3

TRACE 只是OutputDebugString的一个宏。因此,您可以轻松地制作自己的 TRACE 宏(或称其为其他名称)来调用OutputDebugString

于 2008-08-26T09:31:32.913 回答
2

这是我见过的最简单的代码

#undef ATLTRACE
#undef ATLTRACE2

#define ATLTRACE2 CAtlTrace(__FILE__, __LINE__, __FUNCTION__)
#define ATLTRACE ATLTRACE2

http://alax.info/blog/1351

于 2014-09-04T05:13:32.310 回答
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.
}
于 2008-08-26T09:30:12.260 回答