C中的一级宏扩展

One level macro expansion in C

我在一个库中工作,该库是其他库的接口,具有多个已定义的宏,例如:

#define GPIOx  some stuff
#define __HAL_RCC_GPIOx_CLK_ENABLE() some other stuff

其中 x 是一个字母 (A,B,C,...)。

我不能改变这些宏(或者我不应该改变它们,因为它们被其他组件使用)。

在我工作的库中,我试图定义一些用户可以修改的其他宏,例如:

#define DHT_GPIO_Port  GPIOx

我想定义一个宏,它使用这样的定义来生成另一个宏名称:

#define __HAL_DHT_CLK_ENABLE(DHT_GPIO_Port)  __HAL_RCC_## DHT_GPIO_Port ##_CLK_ENABLE()

这是因为我想为我的库使用宏而不是 __HAL_RCC_GPIOx_CLK_ENABLE(),因为它会根据用户定义的 GPIO 而有所不同。

但是,当我尝试使用我的 __HAL_DHT_CLK_ENABLE(DHT_GPIO_Port) 宏时,它会扩展为 __HAL_RCC_DHT_GPIO_Port_CLK_ENABLE(),而不是 __HAL_RCC_GPIOx_CLK_ENABLE()。

另一方面,我尝试将它放在另一个宏中,但它也扩展了 GPIOx,而我不需要。

也许,这是一个初学者的问题,但你能帮忙在另一个宏连接中只展开宏DHT_GPIO_Port的第一层吗?

以下应该有效:

#define __HAL_DHT_CLK_ENABLE_(DHT_GPIO_Port)  __HAL_RCC_## DHT_GPIO_Port ##_CLK_ENABLE()

定义 __HAL_DHT_CLK_ENABLE(DHT_GPIO_Port) __HAL_DHT_CLK_ENABLE_(DHT_GPIO_Port)

例如下面一行:

__HAL_DHT_CLK_ENABLE(GpioA)

产生:

__HAL_RCC_GpioA_CLK_ENABLE()

没有太大意义。而不是无用的难以阅读的宏使用内联函数

#define SINLINE static inline __attribute__((always_inline))

SINLINE void  __HAL_DHT_CLK_ENABLE(GPIO_TypeDef * const gpio)
{
    switch((uint32_t)gpio)
    {
        case (uint32_t)GPIOA:
            __HAL_RCC_GPIOA_CLK_ENABLE();
            break;
        case (uint32_t)GPIOB:
            __HAL_RCC_GPIOA_CLK_ENABLE();
            break;
        case (uint32_t)GPIOC:
            __HAL_RCC_GPIOA_CLK_ENABLE();
            break;
    }
}

当您启用优化并使用常量表达式调用它时(如 GPIOAGPIOBswitch ... case 将被优化。您还可以使用非常量调用它参数 - 你不能用宏来做。

避免像牙菌斑这样的宏。