如何不直接写函数名调用X宏生成的特定GPIO设置函数
如何间接调用X宏生成的GPIO控制函数?
刚好碰到过类似的场景,给你几个实用的解决方案,完全符合你要的不用直接写死函数名、保持代码通用性的需求:
方案1:用宏直接映射引脚名到函数调用
这是最简单的预处理级解决方案,完全不需要额外代码,直接通过宏拼接生成函数调用:
首先保留你已有的CPLD_GPIOs定义:
/* X(pin_name, pin_nb) */ #define CPLD_GPIOs \ X(Pin0, 0) \ X(Pin1, 1) \ X(Pin2, 2) \ X(Pin3, 3)
然后新增两个用来生成函数调用的宏:
// 生成SetOn系列函数的调用 #define SET_ON_GPIO(pin) SetOn_GPIO##pin() // 生成SetOff系列函数的调用 #define SET_OFF_GPIO(pin) SetOff_GPIO##pin()
之后在你的foo函数里就可以这么用:
void foo () { /* some code */ // 预处理后会直接变成 SetOn_GPIOPin2(); SET_ON_GPIO(Pin2); /* some code */ }
这个方案的优势是零运行时开销,代码可读性强,而且只要修改CPLD_GPIOs的引脚列表,所有调用处自动适配,完全不用改业务代码。
方案2:函数指针数组(适合动态选择引脚的场景)
如果你的需求是运行时动态选择引脚(比如从配置文件读引脚号、根据外部状态切换引脚),可以用X宏生成函数指针数组,通过引脚编号间接调用:
首先先按你的方式生成所有SetOn/SetOff函数:
// 生成SetOn系列函数 #define X(pin_name, pin_nb) \ static void SetOn_GPIO##pin_name (void) { \ SetOn_GPIOpins(pin_nb); \ } CPLD_GPIOs #undef X // 生成SetOff系列函数 #define X(pin_name, pin_nb) \ static void SetOff_GPIO##pin_name (void) { \ SetOff_GPIOpins(pin_nb); \ } CPLD_GPIOs #undef X
然后用X宏生成对应的函数指针数组:
// 定义函数指针类型 typedef void (*GPIO_SetFunc)(void); // 生成SetOn函数指针数组 #define X(pin_name, pin_nb) SetOn_GPIO##pin_name, static const GPIO_SetFunc SetOn_GPIO_Funcs[] = { CPLD_GPIOs }; #undef X // 生成SetOff函数指针数组 #define X(pin_name, pin_nb) SetOff_GPIO##pin_name, static const GPIO_SetFunc SetOff_GPIO_Funcs[] = { CPLD_GPIOs }; #undef X
调用的时候直接用引脚编号索引数组即可:
void foo () { /* some code */ // 比如这个引脚号是动态获取的(比如从寄存器、配置读) int target_pin = 2; // 预处理+编译后会调用SetOn_GPIOPin2() SetOn_GPIO_Funcs[target_pin](); /* some code */ }
注意:要保证X宏里的pin_nb是连续的非负整数,这样数组索引才和引脚编号一一对应;如果有不连续的引脚号,空缺位置可以用NULL填充,避免越界。
方案3:引脚名+编号映射(兼顾可读性和灵活性)
如果想同时保留引脚名的可读性和动态调用的灵活性,可以先把引脚名映射成编号,再结合函数指针数组:
// 用X宏生成引脚名到编号的宏定义 #define X(pin_name, pin_nb) #define GPIO_PIN_##pin_name pin_nb CPLD_GPIOs #undef X
然后调用的时候就可以用引脚名来索引数组:
void foo () { /* some code */ // 同样会调用SetOn_GPIOPin2(),但代码更易读 SetOn_GPIO_Funcs[GPIO_PIN_Pin2](); /* some code */ }
额外提示
不管用哪种方案,核心都是复用你的CPLD_GPIOs X宏定义——所有的函数生成、调用映射都基于这个列表,以后要新增/修改引脚,只需要修改CPLD_GPIOs这一处,其他代码完全不用动,完美保持了代码的通用性。
内容的提问来源于stack exchange,提问作者Umaiki
相关产品推荐
相关产品推荐

