8

在 MFC C++ (Visual Studio 6) 中,我习惯于使用 TRACE 宏进行调试。普通的win32是否有等效的声明?

4

7 回答 7

9

_RPTn 效果很好,虽然不是很方便。 下面是一些将 MFC TRACE 语句重新创建为允许可变数量参数的函数的代码。还添加了 TraceEx 宏,该宏在源文件和行号之前添加,因此您可以单击返回到语句的位置。

更新:CodeGuru 上的原始代码在发布模式下无法为我编译,因此我更改了在发布模式下删除 TRACE 语句的方式。这是我放入 Trace.h 的完整源代码。 感谢 Thomas Rizos 的原作

// TRACE macro for win32
#ifndef __TRACE_H__850CE873
#define __TRACE_H__850CE873

#include <crtdbg.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#ifdef _DEBUG
#define TRACEMAXSTRING  1024

char szBuffer[TRACEMAXSTRING];
inline void TRACE(const char* format,...)
{
    va_list args;
    va_start(args,format);
    int nBuf;
    nBuf = _vsnprintf(szBuffer,
                   TRACEMAXSTRING,
                   format,
                   args);
    va_end(args);

    _RPT0(_CRT_WARN,szBuffer);
}
#define TRACEF _snprintf(szBuffer,TRACEMAXSTRING,"%s(%d): ", \
                &strrchr(__FILE__,'\\')[1],__LINE__); \
                _RPT0(_CRT_WARN,szBuffer); \
                TRACE
#else
// Remove for release mode
#define TRACE  ((void)0)
#define TRACEF ((void)0)
#endif

#endif // __TRACE_H__850CE873
于 2009-01-16T20:35:27.667 回答
3

来自 msdn 文档,用于报告的宏

您可以使用 CRTDBG.H 中定义的 _RPTn 和 _RPTFn 宏来代替使用 printf 语句进行调试。当未定义 _DEBUG 时,这些宏会在您的发布版本中自动消失,因此无需将它们包含在 #ifdefs 中。

于 2009-01-16T20:05:37.650 回答
3

还有OutputDebugString。但是,在编译版本时不会删除它。

于 2009-01-16T22:16:14.267 回答
2

我只是使用这样的东西(从记忆中,根本没有测试......)

#define TRACE(msg) {\
    std::ostringstream ss; \
    ss << msg << "\n"; \
    OutputDebugString(msg.str()); \
}

然后我可以写这样的东西:-

TRACE("MyClass::MyFunction returned " << value << " with data=" << some.data);

您可以将其包装在一些#ifdefs 中,以便在发布版本中轻松删除它。

于 2012-10-31T15:08:06.800 回答
1

提供带有源代码链接的消息、运行时调用堆栈信息和带有参数值的函数原型信息的跟踪宏:

扩展跟踪:Win32 的跟踪宏

于 2009-01-30T09:30:47.683 回答
1

我发现_RPT()在 Visual Studio 2005 中使用该宏也适用于 C 源文件。这篇使用 Visual Studio 2005/2008 进行调试:日志记录和跟踪提供了 TRACE、_RPT 和其他日志记录类型宏的概述。

我为名为 ASSRTLOG 的日志文件生成一行,其中包含日志,当将日志写入文件时,我还执行以下源代码行:

_RPT1(_CRT_WARN, "ASSRTLOG: %s", szLog1);

此行将进入日志文件的相同日志放入 Visual Studio 2005 IDE 的输出窗口。

您可能对我们用于日志记录的方法背后的机制感兴趣。我们有一个函数PifLogAbort(),它接受一系列参数,然后用于生成日志。这些参数包括生成日志的文件的名称以及行号。宏如下所示:

#define NHPOS_ASSERT_TEXT(x, txt) if (!(x)) { PifLogAbort( (UCHAR *)  #x , (UCHAR *)  __FILE__ , (UCHAR *) txt , __LINE__ );}

函数原型PifLogAbort()如下所示:

PifLogNoAbort(UCHAR *lpCondition, UCHAR *lpFilename, UCHAR *lpFunctionname, ULONG ulLineNo)

并使用宏,我们将插入这样的一行:

NHPOS_ASSERT_TEXT(sBRetCode >= 0, "CliEtkTimeIn():  EtkTimeIn() returned error");

这个宏的作用是,如果返回码小于 0(断言失败),将使用提供的文本生成一个日志。日志包括生成日志的条件以及文件名和行号。

该函数PifLogAbort()生成具有指定长度的日志并将输出文件视为循环缓冲区。日志也有时间和日期戳。

在我们希望在运行时动态生成描述性文本的情况下,也许是为了提供实际的错误代码值,我们使用带有缓冲区的 sprintf() 函数,如下代码序列:

if (sErrorSave != STUB_BM_DOWN) {
    char xBuff[128];
    sprintf(xBuff, "CstSendBMasterFH: CstComReadStatus() - 0x%x, sError = %d", usCstComReadStatus, CliMsg.sError);
    NHPOS_ASSERT_TEXT((sErrorSave == STUB_BM_DOWN), xBuff);
}

如果我们不想生成日志,我们需要做的就是转到定义宏的单个头文件并将其定义为空,然后重新编译。然而,我们发现这些日志在调查现场问题时非常有价值,并且在集成测试期间特别有用。

于 2012-10-31T15:01:57.363 回答
0

Windows 事件TRACE宏的潜在替代品,具体取决于您的特定方案。代码被编译到调试和发布配置中。然后可以动态启用和禁用事件跟踪、实时显示或转储到客户端机器上以供以后诊断。跟踪也可以与从操作系统的其他部分收集的跟踪信息相关联。

如果您只需要在代码到达某些检查点时转储信息,以及变量内容、堆栈跟踪或调用方名称,Visual Studio 的Tracepoints是一个非侵入式选项。

于 2014-12-09T14:13:40.287 回答