c 预处理器宏在扩展后连接参数

标签 c macros embedded avr atmega

我正在为 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);

Here is a demo

可能的陷阱:

如果PORTA是一个定义的符号,它也会在第二遍时被扩展。因此,如果您有一行诸如

#define PORTA XXX

在代码中的某个地方,它将扩展为

GPIO_Init(XXX__,1,2,3);

关于c 预处理器宏在扩展后连接参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48465770/

相关文章:

linux - DeviceTree 中的命名 GPIO

c - 转义换行符是 POSIX make 的一部分吗?

swift - 带有 return 语句的宏的替代方案

VBA将值粘贴到下一个空单元格中

VBA 从网页中查找文本

Cortex R5 - 启动代码

c - 使用 MPLAB X IDE C18 编译器编译我的 Microchip PIC18f4550 USB 项目时出现问题。编译器一直高亮显示 "syntax error"并且不会编译

c - 开始程序有问题

c - 将华氏度转换为摄氏度时不理解输出

c - 从文件中读取一行并将其存储在变量中