【问题标题】:How to define a macro that can be used to log function calls in C?如何定义可用于在 C 中记录函数调用的宏?
【发布时间】:2011-10-27 14:18:10
【问题描述】:

我发现了一些使用宏 NAME() 包装函数调用的代码,

#define NAME(x) x
...
m_strTemp.Format("x key:0x%X", NAME(a_function)(a_param));

问题是如何定义 NAME() 宏,以便记录使用 TRACE() 调用的函数。

#define NAME(x) TRACE("x");x 之类的东西不起作用,因为由 NAME() 宏包装的函数可能会返回一些东西,有时它们会像上面的示例一样使用。

注意,这必须与 VC++ 2010 编译器一起使用。

【问题讨论】:

    标签: visual-c++ macros c-preprocessor


    【解决方案1】:

    这可能会做你想要的:

    #define NAME(x) (TRACE(#x), x)
    

    (请注意,您可以将函数指示符括在括号中,例如,(strlen)("foo") 是允许的)。

    【讨论】:

    • @sorin:不,你没有。 NAME(x)(foo)的值是调用x(foo)的结果。
    • @sorin:想想看:a = NAME(x)(foo) ;
    • TRACE 不在gcc?
    【解决方案2】:

    我不能 100% 确定 TRACE 的工作原理,但我想将您转至 # macro quoting operator

    【讨论】:

      【解决方案3】:

      我不确定您的一般问题(与Aspect Oriented Programming 相关)是否有解决方案。

      如果您使用 GCC 并且它是最新版本 (4.6),您可以考虑制作一个 GCC 插件,将您的一些调用替换为例如一系列调用,这将替换程序的内部 Gimple 表示(GCC 内部)内部,像 x=f(y,z) 这样的调用与像 debugprint2(y,z); x=f(y,z); debugprint1(z) 这样的序列等。 但这在 C 中编码并不是很简单。您可以考虑使用GCC MELT(一种用于扩展 GCC 的高级域特定语言)进行编码。但是无论如何扩展 GCC 并不是很简单,只有当你的应用程序足够大时才值得(需要几周的工作)

      【讨论】:

        【解决方案4】:

        对于 gcc,有一个名为 gcc function instrumentation 的功能。它允许您收到每个函数调用的通知并采取行动(例如记录)。也许您可以将部分代码导入 linux,或者 VS 也有类似的选项。

        【讨论】:

          【解决方案5】:

          我有一个类似的问题,我想在使用调试器时使用 Visual Studio 2005 的 TRACE 宏在输出窗口中显示日志。但是源文件是 C 源而不是 C++,它们也没有以任何方式使用 MFC 框架,所以我被卡住了。

          然后我找到了这篇文章Debugging with Visual Studion 2005/2008: Logging and Tracing,它首先描述了 TRACE 宏,然后是其他一些机制。我选择使用的是 _RPT1() 宏,它允许我将 TRACE 类型的消息放入 C 源文件中 Visual Studio 调试器的输出窗口中。

          它需要包含 crtdbg.h 头文件,就像各种 TRACE 宏一样,有几个不同的 _RPT 宏,具体取决于参数的数量。

          这并不是这个特定问题的真正答案,但是我想记录在 Visual Studio 2005 中获取调试输出的这种方式,作为 C 源文件中 TRACE 宏的替代方法。

          【讨论】:

            猜你喜欢
            • 2020-03-22
            • 2011-05-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-05-07
            • 2018-07-22
            相关资源
            最近更新 更多