我正在为 avr gpio 编写一个驱动程序,我有一个接受枚举输入的函数。我制作了一个宏,在将端口名称与“__”连接后调用此函数,因此我始终可以使用 initPort(PORTA,1,...)。
#define initPort(port,mask,dir,pullup) GPIO_Init(port ## __,mask,dir,pullup)
typedef enum {
PORTA__,
PORTB__,
PORTC__,
PORTD__
} PORT;
void GPIO_Init(PORT p, uint8_t pins, Direction dir,uint8_t pullup) {
switch (p) {
case PORTA__:
现在,当我想使用该函数时,我使用: initPort(PORTA,1,...) ,这工作正常。 问题是当我想使用类似的东西时:
#define LED_PORT PORTA
initPort(LED_PORT,1,...)
现在发生的情况是 GPIO_Init 的参数现在是 LED_PORT__ 而不是 PORTA__
可以解决这个问题还是我必须使用其他方法?
最佳答案
您实际上可以通过强制预处理器在之前执行一次额外的传递来做到这一点:
#define initPortS(port,mask,dir,pullup) GPIO_Init(port ## __,mask,dir,pullup)
#define initPort(...) initPortS(__VA_ARGS__)
#define LED_PORT PORTA
initPort(LED_PORT,1,2,3);
这样就可以了:
第一遍:
initPort(LED_PORT,1,2,3); -> initPortS(PORTA,1,2,3);
第二遍:
initPortS(PORTA,1,2,3); -> GPIO_Init(PORTA__,1,2,3);
可能的陷阱:
如果PORTA
是一个定义的符号,它也会在第二遍时被扩展。因此,如果您有一行诸如
#define PORTA XXX
在代码中的某个地方,它将扩展为
GPIO_Init(XXX__,1,2,3);
关于c 预处理器宏在扩展后连接参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48465770/