具有令牌连接的C ++宏参数?

时间:2016-07-04 21:03:48

标签: c++ macros c-preprocessor

我有一堆标记的伺服器,每个都有自己校准的最小,中间和最大脉冲宽度值。

// repository of calibrated servo pulse width values:

#define SERVO_0x01_MIN 165
#define SERVO_0x01_MID 347
#define SERVO_0x01_MAX 550

#define SERVO_0x02_MIN 165
#define SERVO_0x02_MID 347
#define SERVO_0x02_MAX 550
...

为了简化代码的维护,交换伺服只需更改单个宏定义值。

// maps certain positions on robot to the servo that is installed there
#define JOINT_0 0x02
#define JOINT_1 0x05
#define JOINT_2 0x0A
...

// function-like macros to resolve values from mapping
#define GET_MIN(servo) SERVO_##servo##_MIN
#define GET_MID(servo) SERVO_##servo##_MID
#define GET_MAX(servo) SERVO_##servo##_MAX

我遇到的问题是调用一个类似函数的宏,其参数本身就是一个宏,并没有解析为它的终值:

// main
int main(void) {

    // this works
    int max_0x01 = GET_MAX(0x01);  // int max_0x01 = 550;

    // this doesn't
    int max_joint_0 = GET_MAX(JOINT_0);  // int max_joint_0 = SERVO_JOINT_0_MAX;
}

如何才能使GET_MAX(JOINT_0)变成550

1 个答案:

答案 0 :(得分:3)

#define GET_MAX(servo) GET_MAX2(servo)
#define GET_MAX2(servo) SERVO_##servo##_MAX

预处理器将对可变参数宏执行扩展(文本替换),直到它不再扩展为止。因此传入JOINT_0,例如GET_MAX(JOINT_0)将扩展为

GET_MAX2(0x02)

这进一步扩展到

SERVO_0x02_MAX

最后替换为#define值550