我有一个Linux应用程序运行在我的桌面上,我想将syslog()调用redirect到printf()调用。
注:我不想取代电话,只是redirect
所以我写了一些代码来做到这一点:
#ifndef EMbed #define syslog(level,stuff) printf("SYSLOG: %sn",stuff) #endif
在我使用的一个文件中效果很好。 我把这个移动到一个新的文件,并得到一个错误:
DirectShow编译问题
Qt编译 – 在Windows上使用qmake
在C ++中使用CMake(mingw)在CLion中引用未定义的Qt5引用
WaitForSingleObject问题
如何从C ++中的一个扬声器播放声音?
error: macro "syslog" passed 3 arguments,but takes just 2
我知道这个错误是因为新文件中的调用是混合的,有些是使用2个参数到syslog,有些正在使用3.我也知道我需要以某种方式通过variables参数列表redirect,但是我怎么做呢? 我还没有得到它的工作呢…
据我所知,syslog()和printf()应该是:
void syslog(int priority,const char *format,...) int printf(const char *format,...)
所以我试了一下:
#define ERR 3 #ifndef EMbed // This is not defined in my env,btw #define syslog(pri,fmt,...) printf(fmt,...) #endif ... void main() { ... syslog(ERR,"test");
但是这给了错误:
error: expected expression before '...' token
关于如何使用这个macros的build议?
MS蓝牙堆栈文档
如何编译和build立在Windows手写的makefile的c + +应用程序?
数字时钟程序在C中使用中断?
read()在套接字编程中不被阻塞
#define syslog(priority,...) printf(__VA_ARGS__)
优先是强制性的,但被宏观扩张忽略。 其余的参数(强制格式加上可选的下面参数)在参数列表中用于printf()的__VA_ARGS__中。 无论格式字符串是常量(文字)还是变量,这都可以。
如果你想把输出标记为syslog()的代理,我会调用printf()以外的printf()来完成这个工作:
#define syslog(priority,...) syslog_print(__VA_ARGS__)
甚至
#define syslog(priority,...) syslog_print(__FILE__,__LINE__,__func__,__VA_ARGS__)
这些将被宣布为:
extern void syslog_printf(const char *fmt,...);
要么:
extern void syslog_printf(const char *file,int line,const char *func,const char *fmt,...);
该实现是<stdarg.h>加上v*printf()函数的宏的直接应用:
void syslog_printf(const char *file,...) { va_list args; printf("SYSLOG:%s:%d:%s: ",file,line,func); va_start(args,fmt); vprintf(fmt,args); va_end(args); }
你可以添加时间戳和任何你喜欢的东西; 你也可以很容易地安排输出到文件而不是标准输出; 您也可以安排它在功能内部打开或关闭。 所以,平均而言,我会用一个替代品代替syslog() ,它允许你调整你的代码使用设施。
实际上,由于你已经发现了改变日志记录行为的要求,所以我建议你不要直接在代码中使用syslog() ,而应该使用自己的函数(例如syslog_printf() ,但可能在一个不同的名字)在你的代码中,并且可以使用该函数的各种实现。 这样做唯一的缺点是调用真正的syslog()现在比较困难 – 没有vsyslog() AFAIK。 因此,对syslog()的基本调用可以通过使用vsnprintf() (或vasprintf()在syslog_printf()对字符串进行格式化vasprintf()如果可用,并且内存耗尽不是可能的问题),然后调用syslog()与预先格式化的字符串( syslog(priority,"%s",buffer); )。 当然,你也希望通过代理函数传递给syslog()的优先级。
fmt字符串应该包含自己的格式化说明符,它们用可变参数填充。 首先,您可以简单地忽略实际的参数,然后打印格式化字符串。 你需要一个可变的宏:
#define syslog(level,...) printf("SYSLOG: %sn",fmt)
其次,如果你愿意承担巨大的风险,并期望用户提供格式化字符串作为一个文字而不是一个变量,你可以连接你自己的字符串:
#define syslog(level,...) printf("SYSLOG[%d] " fmt,level,##__VA_ARGS__)
这将为syslog(1,"Hello"); ,但不适用于syslog(1,str); 。
如果你不想依赖可变宏(C99特性),你也可以这样做:
#define syslog my_syslog static inline int my_syslog(int prio,...) { int r; va_list ap; va_start(ap,fmt); r = vprintf(fmt,ap); va_end(ap); return r; }
或类似的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。