'VA_ARGS',宏Obj-C

时间:2017-03-26 16:48:16

标签: objective-c

我使用以下技术来管理我的日志。我打印日志到asl_log之前,关于标记[DebugManager shared] isDebugging我想将日志行发送到其他类(方法addLogEvent

#if !defined(TheLog)
#define TheLog(fmt, ...) { \
if ([[DebugManager shared] isDebugging]) \
     addLogEvent(__PRETTY_FUNCTION__,fmt,##__VA_ARGS__); \
}
#endif

#define __AF_MAKE_LOG_FUNCTION(LEVEL, NAME) \
inline void NAME(NSString *format, ...)\
{ \
 TheLog(__PRETTY_FUNCTION__,format,##__VA_ARGS__);\ 
va_list arg_list; \
va_start(arg_list, format); \
NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arg_list]; \
asl_add_log_file(NULL, STDERR_FILENO); \
asl_log(NULL, NULL, (LEVEL), "PREFIX:  %s", [formattedString UTF8String]); \
va_end(arg_list); \
}


// Something has failed.
__AF_MAKE_LOG_FUNCTION(ASL_LEVEL_ERR, AFLogError)

// Something is amiss and might fail if not corrected.
__AF_MAKE_LOG_FUNCTION(ASL_LEVEL_WARNING, AFLogWarning)

// The lowest priority for user log
__AF_MAKE_LOG_FUNCTION(ASL_LEVEL_INFO, AFLogDebug)

我使用__AF_MAKE_LOG_FUNCTION(LEVEL, NAME)映射日志级别,我需要从TheLog(__PRETTY_FUNCTION__,format,##__VA_ARGS__);\

致电inline void NAME(NSString *format, ...)

我收到错误:

Pasting formed ',__VA_ARGS__', an invalid preprocessing token

如何获取,__VA_ARGS____PRETTY_FUNCTION__

1 个答案:

答案 0 :(得分:2)

这一行:

 TheLog(__PRETTY_FUNCTION__,format,##__VA_ARGS__);\ 

是此宏定义的一部分:

#define __AF_MAKE_LOG_FUNCTION(LEVEL, NAME) \

请注意,该宏不采用变量参数列表。因此,在其定义中没有定义__VA_ARGS__

__AF_MAKE_LOG_FUNCTION实例化定义的函数 - inline void NAME() - 采用变量参数列表这一事实并不重要。如果该函数想要将变量参数列表传递给另一个函数,则需要使用stdarg功能,就像-[NSString initWithFormat:arguments:]那样,但这对您的TheLog宏不起作用,因为它不是为了接受va_list而设计的。

你无法做你正在尝试的事情。您的TheLog宏与您尝试使用它的方式不兼容。您需要设计一个替代版本,例如:

#define TheLogv(fmt, args) { \
if ([[DebugManager shared] isDebugging]) \
     addLogEventv(__PRETTY_FUNCTION__,fmt,args); \
}

请注意,这反过来要求存在一个函数addLogEventv(),它接受​​va_list而不是实际的变量参数列表。在由__AF_MAKE_LOG_FUNCTION定义的函数体内,你必须两次开始和结束列表,每次将它传递给另一个函数时,因为每个函数都会“消耗”它:

#define __AF_MAKE_LOG_FUNCTION(LEVEL, NAME) \
inline void NAME(NSString *format, ...)\
{ \
va_list arg_list; \
va_start(arg_list, format); \
 TheLogv(__PRETTY_FUNCTION__,format,arg_list);\ 
va_end(arg_list); \
va_start(arg_list, format); \
NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arg_list]; \
asl_add_log_file(NULL, STDERR_FILENO); \
asl_log(NULL, NULL, (LEVEL), "PREFIX:  %s", [formattedString UTF8String]); \
va_end(arg_list); \
}

您也可以更改TheLog()宏来获取NSString*,然后直接传入已经创建的formattedString