我有一个奇怪的用例,我需要修改在C中传递的变量的名称
#define SET_PROTOBUF_REPEATED(msg_ptr, field_name, src_data, src_data_length)
{
/*
msg_ptr->field_name.len = src_data_length;
*/
// I want to do this
// msg_ptr->n_field_name = src_data_length
/*
msg_ptr->field_name.data = malloc(src_data_length);
memcpy(msg_ptr->field_name.data, src_data, src_data_length);
*/
msg_ptr->field_name = malloc(src_data_length);
memcpy(msg_ptr->field_name, src_data, src_data_length);
}
因为我在协议缓冲区消息中使用重复类型,所以可变长度定义为
n_variable_name
而不是
variable_name.len
例如
variable_name = frequency
// the length have to be n_frequency
我想要有一个宏来执行此操作的原因是因为我有很多protobuf消息重复上述函数的功能。为了便于阅读和模块化,我认为定义一个能够解决这个问题的新功能是个好主意。
非常感谢任何建议
由于
答案 0 :(得分:2)
编写多行宏的规范方法是将其包装在do ... while(0)
语句中。这可以确保宏作为单个语句工作。例如:
#define macro(a,b,c) \
do { \
(a) = (b)*(c); \
} while (0) /* No trailing semi-colon */
...
macro (x, y, z);
for (i = 0; i < n; i++)
macro (x, y, z); /* This wouldn't work properly without do...while(0) */
您应该在宏参数周围加上括号,以避免在有人传递意外参数时出现意外,例如macro (t, 1+2, 3+4);
您还需要一个辅助宏来连接参数。也许你正在寻找这样的东西:
#define CONCAT(x,y) x ## y
#define SET_PROTOBUF_REPEATED(msg_ptr, field_name, src_data, src_data_length) \
do { \
(msg_ptr)->CONCAT(n_,field_name) = (src_data_length); \
\
(msg_ptr)->(field_name) = malloc((src_data_length)); \
memcpy((msg_ptr)->(field_name), (src_data), (src_data_length)); \
} while (0)