我需要C语言中的日志功能或宏,它应该在Linux中工作,可以接受格式字符串和参数列表,并且可以将调用者的函数名称附加到输出字符串。
这是一个例子。假设日志记录功能(宏)称为smart_log。它看起来像:
smart_log(const char *fmt, ...)
第一个参数fmt是一个格式字符串,就像printf中的格式字符串一样。 fmt之后是一个供给fmt的其他参数列表。
假设一个名为example_function的函数以这种方式调用smart_log:
void example_function() {
smart_log("try to output number %d\n", 1);
}
然后日志字符串看起来像:
[example_function]: try to output number 1
所以关键是smart_log将调用者函数附加到格式字符串。
我不知道如何在C中实现这一点。我认为可以使用宏来实现这一点。
答案 0 :(得分:6)
没有可移植的方法让函数在C中知道它的调用者。但是你是对的,宏工作:
#define smart_log(...) ( printf("[%s]: ", __func__) , printf(__VA_ARGS__) )
__func__
已定义(C99 / C11 6.4.2.2第1页)
就好像紧跟在每个函数定义的左大括号之后的声明
static const char
__func__
[] = "function-name";出现,其中 function-name 是词法封闭函数的名称。
感谢Hagen von Eitzen改善了原来的尝试!
答案 1 :(得分:2)
这是非常依赖于系统/编译器的,因为获取函数名称的确切含义在很大程度上取决于编译器。对于Visual C ++,您可以使用宏__FUNCTION__
在编译时获取当前函数名。
为了确保在没有将宏放入smart_log
的每次调用的情况下记录正确的函数名,您可以通过宏调用日志函数,以便获取函数名称的宏正确的上下文 - 如果您简单地将宏添加到函数名称,您将始终获得日志记录函数的名称...
所以不要叫这个:
smart_log("log message");
你打电话:
SMART_LOG("log message");
反过来定义为:
#define SMART_LOG(message) smart_log(__FUNCTION__, message)
这是假设您的日志函数将函数名称作为第一个参数,因此调整以适应。
答案 2 :(得分:2)
如果您不想使用宏,可以使用堆栈。 smart_log
函数将位于调用它的函数之上。
答案 3 :(得分:1)
定义一个宏 - SMART_LOG - 将__FILE__
,__FUNCTION__
和__LINE__
作为参数传递给smart_log
。然后,无论何时使用SMART_LOG
,它都会自动向smart_log
提供调用者的代码位置。但请注意,__FUNCTION__
是非标准的,但在GCC中可用(和Visual C,所以我相信),请参阅:https://stackoverflow.com/a/597081/191492)。