c - 使用 X 宏的特定条目
问题描述
我正在使用 X 宏来生成将 GPIO 设置为0
或的函数1
(我生成了大约 60 个函数来设置大约 30 个 GPIO)。这是一个例子(我刚刚写了这个例子,所以语法可能是错误的):
/* X(pin_name, pin_nb) */
#define CPLD_GPIOs \
X(Pin0, 0) \
X(Pin1, 1) \
X(Pin2, 2) \
X(Pin3, 3)
我生成访问这些 GPIO 的函数:
#define X(pin_name, pin_nb) \
static void SetOn_GPIO##pin_name (void) { \
SetOn_GPIOpins(pin_nb);\
}
CPLD_GPIOs
#undef X
函数也存在相同的过程SetOff_GPIOXXX
。
SetOn_GPIOPin2
有没有一种方法可以像在程序的其他部分一样访问编译器生成的函数,而无需直接编写函数名?(为了使代码尽可能全局化)
在预处理结束时,我们应该只SetOn_GPIOPin2();
(而不是每个X-macro条目)从 X-Macro 生成。
预处理前:
void foo ()
{
/* some code */
/*
* Macro to generate the desired function.
* For e.g: SetOn_GPIOPin2();
*/
/* some code */
}
预处理后:
void foo ()
{
/* some code */
/* Function resulting of the pre-processing */
SetOn_GPIOPin2();
/* some code */
}
解决方案
从对该问题的评论来看,您的目标似乎是防止您的 X 宏被修改以产生不同名称的函数的情况。如果是这样,那么我认为您正在为自己做不必要的工作:这些名称是否被更改是在您(以及任何其他项目开发人员)的控制之下,并且您担心的名称更改不会被忽视很长时间. 所以不要改变它们。
但是,如果您决定走这条路,那么不,没有办法让预处理器从较大的替换文本中提取宏生成的函数名称。相反,您需要通过同一个宏将它们注入到 X 宏和您的其他代码中。像这样,也许:
/* X(pin_name, pin_nb) */
#define CPLD_GPIOs(gen) \
X(Pin0, 0, gen) \
X(Pin1, 1, gen) \
X(Pin2, 2, gen) \
X(Pin3, 3, gen)
// Generates the wanted function names:
#define GPIO_ON(pin_name, pin_nb) SetOn_GPIO##pin_name
#define X(pin_name, pin_nb, gen) \
static void gen(pin_name, pin_nb) (void) { \
SetOn_GPIOpins(pin_nb);\
}
CPLD_GPIOs
#undef X
// ...
void some_function(void) {
GPIO_ON(pin_name, pin_nb)();
}
但请注意,尽管此技术可能有其他应用,例如使用相同的X
宏集生成多组函数,但它只是针对您所描述的特定目标将罐子踢了下去。您可以依靠名称生成器宏为函数声明和函数调用生成相同的名称,但您仍然存在X
可以修改宏以生成具有不同名称的函数声明的问题。
推荐阅读
- sql - 将一个表中的记录插入到另一个表中,递增 id
- angular - 如何将 Angular 配置为在开发模式下服务,但使用选定的生产环境变量?
- android - 是否可以将 adb 命令批量设置为变量?
- azure - Azure Functions BlobTrigger blobPath 嵌套配置绑定
- java - AtomicReference compareAndSet:字符串引用与值相等
- tableau-api - 将 Tableau 数据导出为 CSV
- kubernetes - 限制对服务帐户的访问
- c# - .NET Core 3 / EF.Core 3:`QueryModelGenerator`、`RelationalQueryModelVisitor` 等发生了什么
- go - 使用 Go 的 base64.StdEncoding.Decode() 方法:如何选择目标字节片的大小?
- java - 抛出异常时无法捕获异常