gpt4 book ai didi

android - 我应该如何在 C 中连接宏?

转载 作者:太空宇宙 更新时间:2023-11-04 08:03:50 25 4
gpt4 key购买 nike

我正在尝试创建一个日志助手,并希望将行号连接到日志信息。

我想完成这样的日志:("-l:"+ LINE + args)

05-22 15:04:16.626 21270-22699/com.mydomain.myproject D/myfile.c: -l:5 myloginfo ...

这是我的 loghelper.h 文件中的内容:

#ifdef __ANDROID__
#include <android/log.h>
#define FILETAG (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#define LINEIDENTIFIER ' -l:'
#define TOKENAPPEND(x, y, z) x##y##z
#define APPENDLINE(x, y, z) TOKENAPPEND(x, y, z)
#define printf(fmt,args...) __android_log_print(ANDROID_LOG_DEBUG, FILETAG , fmt, APPENDLINE(LINEIDENTIFIER, __LINE__, ##args))
#define printfe(fmt,args...) __android_log_print(ANDROID_LOG_ERROR, FILETAG, fmt, APPENDLINE(LINEIDENTIFIER, __LINE__, ##args))
#define printfw(fmt,args...) __android_log_print(ANDROID_LOG_WARN, FILETAG, fmt, APPENDLINE(LINEIDENTIFIER, __LINE__, ##args))
#endif

像这样从 myfile.c 调用:

#include "loghelper.h"

...

printf(" myloginfo %s", "...");

我收到以下错误:

error: pasting formed '' -l:'52', an invalid preprocessing token
error: expected ')'
error: too many arguments provided to function-like macro invocation
error: use of undeclared identifier 'APPENDLINE'
error: pasting formed '57"success!"', an invalid preprocessing token
error: expected ')'

问:我做错了什么?我应该更改什么才能使其正常工作?

最佳答案

您尝试在无法使用的地方使用标记粘贴运算符 ##。 token 粘贴可用于创建新 token ,通常是新标识符:

#define MY(X) my_##X     // MY(func) -> my_func

在这里,您想要连接字符串文字。这里有两点需要注意:

  • 您不需要预处理器来连接字符串文字。 C 语法将连接相邻的字符串文字:"to""gether" 将被视为 "together"
  • __LINE__ 宏扩展为整数,因此您必须将其转换为字符串文字。字符串化运算符# 对特殊标记__LINE__ 不起作用,因此您必须编写一个宏来进行字符串化。如果这样做,您会得到字符串文字 "__LINE__",这不是很有用。使用 double stringizing ,即再添加一层间接寻址,以将实际行号作为字符串。

将所有这些付诸实践,一个简单的日志记录宏可能如下所示:

#define M_STR_(x) #x
#define M_STR(x) M_STR_(x)

#define LOG(...) fprintf(stderr, "Line " M_STR(__LINE__) ": " __VA_ARGS__)

为了简单起见,我在这里使用了一个较短的示例。需要注意的是:

  • 我在这里使用了标准的 ...__VA_ARGS__ 表示法,并且我没有拆分格式字符串和宏参数列表中的参数。这样,宏将在不打印参数的情况下工作,并且您不需要非标准的 ##__VA_ARGS__ 来抑制单独的逗号。
  • 这个宏只有在格式字符串是字符串文字时才有效,因为它应该是。格式字符串 "%s" 将扩展为 "Line ""12"": ""%s"
  • 将字符串文字添加到格式字符串的前面很容易,但追加到它就更复杂了,例如,如果你想用一个新行结束格式字符串。您可以使用您的方法将 fmt 与 args 分开,但坚持简单的方法可能更容易,并将宏扩展为两个打印语句:一个用于格式化字符串,另一个用于新队。 (但一定要wrap it,这样这两个命令就不能分开了。)

最后,应用于您的 printf 替换的方法:

#define printf(...)                                       \
__android_log_print(ANDROID_LOG_DEBUG, FILETAG, \
"-l " M_STR(__LINE__) ": " __VA_ARGS__)

关于android - 我应该如何在 C 中连接宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44119632/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com