项目里遇到的,结构体里面的最后一个变量是长度为 0 的数组。在这个项目里面用于组包。
柔性数组的特点:
1、柔性数组成员必须定义在结构体里面且为最后元素
2、结构体中不能单独只有柔性数组成员
3、柔性数组不占结构体的内存
这个项目里面的包拆解如下图所示
有两处用到了柔性数组,有一个坑点就是柔性数组不占结构体的内存,所以 malloc 的时候需要多申请空间。
直接从项目里面copy代码吧
组包如下:
void THdasEventDeal::BsdTest() {
// item里面的两个组件
THdasBsdAlarmItem data_item;
data_item.level = kHdasAlarmLevel1;
data_item.rect.left = 5;
data_item.rect.top = 6;
data_item.rect.right = 7;
data_item.rect.bottom = 8;
// data里面的剩下三个
uint32_t data_count = 1;
THdasBsdAlarmType data_type = kBsdAlarmTypeRight;
uint64_t data_time = 666;
// 将这四个组件合起来 柔性数组
THdasBsdAlarm *bsd_alarm = (THdasBsdAlarm *)malloc(sizeof(data_time) + sizeof(data_type) + sizeof(data_count) + sizeof(data_item));
bsd_alarm->time = data_time;
bsd_alarm->type = data_type;
bsd_alarm->count = data_count;
memcpy(bsd_alarm->item, &data_item, sizeof(data_item));
// event的另外两个
THdasEventType event_type = kHdasEventBsd;
size_t event_len = sizeof(data_time) + sizeof(data_type) + sizeof(data_count) + sizeof(data_item);
// 构造event, 将bsd_alarm变成uint8_t数组
THdasEvent *event = (THdasEvent *)malloc(sizeof(event_type) + sizeof(event_len) + event_len);
event->type = event_type;
event->len = event_len;
memcpy(event->data, &*bsd_alarm, event_len);
HdasEventCallBack(handler_, event, this);
}
解包:
void unpack(THdasEvent *event)
{
ylog_debug("------- wsmalarm hdas unpack --------\n");
ylog_info("wsmalarm event->type = %d\n", event->type);
ylog_info("wsmalarm event->len = %d\n", event->len);
ylog_info("wsmalarm ((THdasBsdAlarm*)event->data)->time = %llu\n", ((THdasBsdAlarm*)event->data)->time);
ylog_info("wsmalarm ((THdasBsdAlarm*)event->data)->type = %d\n", ((THdasBsdAlarm*)event->data)->type);
ylog_info("wsmalarm ((THdasBsdAlarm*)event->data)->count = %d\n", ((THdasBsdAlarm*)event->data)->count);
THdasBsdAlarmItem myalarm = (THdasBsdAlarmItem)(((THdasBsdAlarm*)event->data)->item[0]);
ylog_info("wsmalarm myalarm.level = %d\n", myalarm.level);
ylog_info("wsmalarm myalarm.rect.left = %d\n", myalarm.rect.left);
ylog_info("wsmalarm myalarm.rect.top = %d\n", myalarm.rect.top);
ylog_info("wsmalarm myalarm.rect.right = %d\n", myalarm.rect.right);
ylog_info("wsmalarm myalarm.rect.bottom = %d\n", myalarm.rect.bottom);
}