【发布时间】:2017-10-14 04:03:39
【问题描述】:
我尝试了一个多星期没有成功。
我正在两个处理器之间创建一个记录器接口,我需要帮助来定义自动 MACROS。
我是什么意思?
假设我有一个定义为 LOGGER_MSG_ID_2 的记录器消息,它接受 uint8 和 uint16 类型的两个参数。
我有一个枚举定义为:
typedef enum{
PARAM_NONE,
PARAM_SIZE_UINT8,
PARAM_SIZE_UINT16,
PARAM_SIZE_UINT32
}paramSize_e;
所以LOGGER_MSG_ID_2 将有一个位图定义为:
#define LOGGER_MSG_ID_2_BITMAP (PARAM_SIZE_UINT16 << 2 | PARAM_SIZE_UINT8)
这个位图是 1 Byte 大小,所以参数的最大数量是 4。 稍后我有一个根据消息 ID 定义所有参数类型的列表:
#define ID_2_P0_TYPE uint8 // first parameter
#define ID_2_P1_TYPE uint16 // 2nd parameter
#define ID_2_P2_TYPE 0 // 3rd parameter
#define ID_2_P3_TYPE 0 // 4th parameter
正如我所说,我有 4 个参数的限制,所以我想定义它们并让 MACRO 决定天气是否使用它们。我将它们定义为 0,但它可以是任何有效的值。
我还有其他使用位图获取各种属性的 MACROS,例如参数数量和消息大小。
现在是棘手的部分。我想构建一个从类型创建位图的宏。原因是我不希望位图和参数定义之间存在冗余。 我的问题是我尝试的所有内容都无法编译。
最终我想要一个宏,例如:
#define GET_ENUM_FROM_TYPE(_type)
根据类型给我 PARAM_SIZE_UINT8、PARAM_SIZE_UINT16 或 PARAM_SIZE_UINT32。
限制:我在 windows (armcl.exe) 和 C99 上使用 arm 编译器。我无法使用 C11 Generic()。
我尝试了以下方法:
#define GET_ENUM_FROM_TYPE(_type) \
(_type == uint8) ? PARAM_SIZE_UINT8 : \
((_type == uint16) ? PARAM_SIZE_UINT16 : \
((_type == uint32) ? PARAM_SIZE_UINT32 : PARAM_NONE))
最终我想像这样使用它:
#define LOGGER_MSG_ID_2_BITMAP \
(GET_ENUM_FROM_TYPE(ID_2_P3_TYPE) << 6 | \
GET_ENUM_FROM_TYPE(ID_2_P2_TYPE) << 4 | \
GET_ENUM_FROM_TYPE(ID_2_P1_TYPE) << 2 | \
GET_ENUM_FROM_TYPE(ID_2_P0_TYPE))
但是当我使用它时,它不会编译。
我有一张位图表:
uint8 paramsSizeBitmap [] = {
LOGGER_MSG_ID_1_BITMAP, /* LOGGER_MSG_ID_1 */
LOGGER_MSG_ID_2_BITMAP, /* LOGGER_MSG_ID_2 */
LOGGER_MSG_ID_3_BITMAP, /* LOGGER_MSG_ID_3 */
LOGGER_MSG_ID_4_BITMAP, /* LOGGER_MSG_ID_4 */
LOGGER_MSG_ID_5_BITMAP, /* LOGGER_MSG_ID_5 */
LOGGER_MSG_ID_6_BITMAP, /* LOGGER_MSG_ID_6 */
LOGGER_MSG_ID_7_BITMAP, /* LOGGER_MSG_ID_7 */
LOGGER_MSG_ID_8_BITMAP, /* LOGGER_MSG_ID_8 */
LOGGER_MSG_ID_9_BITMAP, /* LOGGER_MSG_ID_9 */
LOGGER_MSG_ID_10_BITMAP, /* LOGGER_MSG_ID_10 */
};
我得到这个错误:
line 39: error #18: expected a ")"
line 39: error #29: expected an expression
(第 39 行是LOGGER_MSG_ID_2_BITMAP)
我哪里出错了?
----- 编辑-----
现在我有一个我不太喜欢的解决方法。
我不使用 uint64,所以我使用了sizeof() MACRO,现在我的 MACRO 看起来像这样:
#define GET_ENUM_FROM_TYPE(_type) \
(sizeof(_type) == sizeof(uint8)) ? PARAM_SIZE_UINT8 : \
((sizeof(_type) == sizeof(uint16)) ? PARAM_SIZE_UINT16 : \
((sizeof(_type) == sizeof(uint32)) ? PARAM_SIZE_UINT32 : PARAM_NONE))
我的参数列表是:
#define NO_PARAM uint64
#define ID_2_P0_TYPE uint8
#define ID_2_P1_TYPE uint16
#define ID_2_P2_TYPE NO_PARAM
#define ID_2_P3_TYPE NO_PARAM
它工作正常,但是......你知道......
【问题讨论】:
-
你检查过预处理后的表格是什么样子的吗?大多数编译器都提供输出预处理源文件的选项。
-
另外,像
GET_ENUM_FROM_TYPE这样的非平凡宏应该用括号括起来。运算符优先级可能会在这里咬你。 -
"This bitmap is 1 Byte size" 那你为什么使用 uint16?没有多大意义。
-
@Lundin ID 是 1 个字节,位图是另一个 1 个字节。 4 个参数,每个 2 位。 4 x 2bit = 8bit = 1 字节
标签: c types macros arm c-preprocessor