【问题标题】:Getting the name of C file who calls a function获取调用函数的C文件名
【发布时间】:2016-04-07 18:19:26
【问题描述】:

我正在用“C”实现一个记录器,核心功能是:

void log(Level tag, const char *message)

此函数将在与我的log.c 文件不同的客户端文件中调用。

我的问题是:

这个函数如何获得调用者文件的名称而不将其作为参数传递(例如添加另一个char *)参数,然后在调用者文件中传递__FILE__

谢谢。

【问题讨论】:

  • 您无法在 log 函数中找到保存调用函数的文件名。 (注意:#include <math.h> 也声明了一个函数 log() — 具有非常不同的签名)。您必须将其作为参数传递。使用宏来自动化:#define LOG(tag, msg) debug_log(__FILE__, tag, msg) 或类似的东西。
  • 你也应该看看#define macro for debug printing

标签: c logging


【解决方案1】:

如果您使用 GCC 并且不介意使用 -rdynamic 进行编译,您可以使用函数 backtrace() 获取回溯,然后使用 dladdr() 查找单个函数的名称(第一个在列表中,由backtrace()) 或backtrace_symbols 返回以获取堆栈中所有函数的符号,并仅使用第一个。

这里有更多细节 - https://stackoverflow.com/a/351980/28494

详情请见man

【讨论】:

    【解决方案2】:

    首先要做的是将log() 重命名为debug_log() 或其他名称,以便您可以使用#include <math.h> 以及日志记录机制。谢谢@JonathanLeffler。

    接下来您要做的是更改debug_log,使其接受文件名作为参数。

    void debug_log(Level tag, const char *message, char const* filename);
    

    然后,添加一个宏来帮助自动使用宏__FILE__

    #define LOG_MESSAGE(tag, message) debug_log((tag), (message), __FILE__)
    

    然后,在客户端代码中使用宏而不是函数。

    LOG_MESSAGE(my_tag, my_message);
    

    【讨论】:

    • 首先要做的是将log() 重命名为debug_log() 或其他名称,以便您可以使用#include <math.h> 以及日志机制:)
    • 这听起来比将所有函数重写到宏中要好。谢谢!
    【解决方案3】:

    改为将其设为宏,始终将__FILE__ 传递给它调用的函数。

    这样记录器调用看起来更干净(你看不到额外的参数)。

    例如,要始终添加函数名称和行号,我使用以下也有可变参数的代码,因此您可以像 printf() 一样使用格式字符串和参数调用它。 这需要 GCC 宏功能。

    #define DBG(x, args...) ({ \
        if (debug) { \
            fprintf(stderr, "%s:%d: " x "\n", __func__, __LINE__, ##args);  \
        } \
    })
    

    【讨论】:

    • 哦,是的。谢谢。我认为这是最好的方法。
    • 是的,我明白了,但问题是我的函数中有很多行,所以我认为下面的答案更适合我的情况。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 2022-12-06
    • 1970-01-01
    相关资源
    最近更新 更多