我正在尝试编写一个宏来简化LOG4CPLUS的使用。但是在编写宏时我遇到了一些麻烦。
这是我的cpp文件中的内容:
Logger logger = Logger::getInstance("ManagerServer");
之后,我可以像这样记录一行:
LOG4CPLUS_ERROR(logger, logEvent);
我只想编写一个宏,而不是将logEvent更改为某个变量参数。并使用这样:
LogErr("failed");
LogErr("failed times %d", iTimes);
所以,我这样写:
#define LogErr(fmt, args...)\
do {\
char szBuf[MAX_LOG_BUFFER_SIZE];\
memset(szBuf, 0, MAX_LOG_BUFFER_SIZE); \
vsnprintf(szBuf, MAX_LOG_BUFFER_SIZE, fmt, ##args); \
LOG4CPLUS_ERROR(logger, szBuf);\
} while(0)
但是当我编译的时候。 g ++给我这条消息:
错误:')'令牌
之前的预期主要表达式
有人可以帮助我吗?我真的很感激。
答案 0 :(得分:2)
糟糕... C标签已被删除
当提供的参数不足( LogErr("failed")
)时,问题在于宏的扩展。这在C中不起作用。
尝试添加虚拟参数
LogErr("failed", 0);
/* or better */
LogErr("%s", "failed");
此外,您无法在宏中使用v*
函数,就像您尝试的那样:预处理器不知道变量参数,广告无法创建va_list
类型的对象。
在C99中,一种方法可以做你想要做的事情
#include <stdio.h>
#include <string.h>
#define MAX_LOG_BUFFER_SIZE 100
#define LogErr(fmt, ...) \
do { \
char szBuf[MAX_LOG_BUFFER_SIZE]; \
memset(szBuf, 0, MAX_LOG_BUFFER_SIZE); \
snprintf(szBuf, MAX_LOG_BUFFER_SIZE, fmt, ##__VA_ARGS__); \
/* LOG4CPLUS_ERROR(logger, szBuf); */ \
} while(0)
int main(void) {
LogErr("err %d", 4);
/*LogErr("failed");*/
LogErr("%s", "failed");
return 0;
}
注意: snprintf
和##__VA_ARGS
答案 1 :(得分:1)
你在args参数后缺少一个逗号。
#define LogErr(fmt, args, ...)\
^
另外,我不知道g ++目前是否支持可变参数宏,它是C ++ 11的一个特性。 (我相信C编译器支持它们。)
答案 2 :(得分:1)
感谢pmg,Ferruccio和所有人。你们真的救了我!
这些代码在我的电脑上运行良好。好像我确实错过了vsnprintf和snprintf。
#define Log(fmt, args...) \
do {\
char szBuf[MAX_LOG_BUFFER_SIZE];\
snprintf(szBuf, MAX_LOG_BUFFER_SIZE-1, fmt, ##args);\
LOG4CPLUS_ERROR(logger, szBuf);\
} while(0)
int main() {
Log("Hello macro.");
Log("Hello macro %d", 1);
Log("Hello macro %s, %d", "foo", 2);
return 0;
}
再次感谢!
答案 3 :(得分:0)
最近(1.1.0+)版本的Log4cplus支持使用printf样式的宏进行日志记录。您在OP中的示例如下所示:
LOG4CPLUS_ERROR_FMT(logger, "failed");
LOG4CPLUS_ERROR_FMT(logger, "failed times %d", iTimes);
如果您仍希望以不同方式重新实现,请参阅loggingmacros.h了解实施细节。