我有以下宏
#define REG_PWR_CTRL 0x2D
#define REG_FIFO_CTL 0x38
#define VERBOSE(...) \
if(verbose) \
printf(__VA_ARGS__);
#define READ_REGISTER(i2c_dev_file, REGISTER, variable) \
{ \
variable = i2c_smbus_read_byte_data(i2c_dev_file, REGISTER); \
}
#define WRITE_REGISTER_VERBOSE(i2c_dev_file, REGISTER, value) \
{ \
short int var = 0; \
i2c_smbus_write_byte_data(i2c_dev_file, REGISTER, value); \
usleep(100); \
READ_REGISTER(i2c_dev_file, REGISTER, var); \
VERBOSE(#REGISTER " :0x%02X\n", var); \
}
我希望REGISTER
在下一行中不要扩展该字段
VERBOSE(#REGISTER " :0x%02X\n", var); \
例如,当我写
WRITE_REGISTER_VERBOSE(i2c_dev_fd, REG_PWR_CTRL, 0x1A);
WRITE_REGISTER_VERBOSE(i2c_dev_fd, REG_FIFO_CTL, 0xC6);
我得到的输出
0x2D :0x1A
0x38 :0xC6
,我想获得
REG_PWR_CTRL :0x1A
REG_FIFO_CTL :0xC6
我遇到了很多关于添加额外级别的间接性的文章。
我尝试了此处描述的答案https://stackoverflow.com/a/2653351/1761555 ..尽管我相信该答案完全是针对另一个问题。
我所做的是
#define STRINGIFY(label) (#label)
#define WRITE_REGISTER_VERBOSE(i2c_dev_file, REGISTER, value) \
{ \
short int var = 0; \
i2c_smbus_write_byte_data(i2c_dev_file, REGISTER, value); \
usleep(100); \
READ_REGISTER(i2c_dev_file, REGISTER, var); \
VERBOSE("%s :0x%02X\n", STRINGIFY(REGISTER), var); \
}
但这仍然给我与以前相同的输出
有什么办法可以做到这一点?
你可以做REG_PWR_CTRL
和REG_FIFO_CTL
一些枚举值,如
enum registers_en {
REG__NONE,
REG_PWR_CTRL = 0x2d,
REG_FIFO_CTL = 0x38,
};
然后REG_PWR_CTRL
成为某个枚举值的真实标识符,并且不会在其他内容中进行宏扩展(因为enum
定义不是宏定义,并且不会由cpp
预处理器处理)。
因此,定义一个枚举,并预处理您的源代码(例如,使用gcc -C -E yoursource.c > yoursource.i
),然后less yoursource.i
在预处理文件中查找(例如,使用)。所有的出现REG_PWR_CTRL
仍会存在。
请注意,从概念上讲,预处理器是编译器的第一阶段:即使在当前GCC 4.8之类的编译器中,该预处理器不是外部程序,而是通过libcpp内部库实现的,编译器的工作方式是先预处理源代码并获取流的词位,然后出现的REG_PWR_CTRL
逗留词位(而不是字面常量0x2d
,当您#define REG_PWR_CTRL 0x2d
......)。
您需要阅读有关预处理器cpp的更多信息,并养成研究预处理形式的习惯。
enum
-s的另一个优点是,如果您使用调试信息(例如gcc -g
)进行编译,则调试器会gdb
知道enum
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句