如何使用msgpack-c正确解压缩和提取数据?

我目前正在尝试在用C编写的项目中使用msgpack。我使用msgpack来序列化结构的内容,然后通过网络发送,然后反序列化为相应的结构。另一边。

我正在尝试做的简明版本:

#include  #include  #include  typedef someStruct{ uint32_t a; uint32_t b; float c; } someStruct; int main (void){ someStruct data; /* ... Fill 'data' with some data for test purposes ...*/ msgpack_sbuffer* buff = msgpack_sbuffer_new(); msgpack_packer* pck = msgpack_packer_new(buff, msgpack_sbuffer_write); someStruct* structs = malloc(sizeof(someStruct) * 10); /* ... Fill 'structs' with members containing test data ... */ // Serialize msgpack_pack_array (pck, 10); int i; for(i = 0 ; i data, buff->size, NULL); if(!deserialize_success) /* Error */ msgpack_object obj = msg.data; msgpack_object_print(stdout,obj); // This seems to work perfectly, indicating serialize / deserialize works as intended... someStruct deserialized_data; /* Insert code to extract and cast deserialized data to 'deserialized_data */ // Clean msgpack_sbuffer_free(buff); msgpack_packer_free(pck); return 0; } 

列出的代码或多或少地直接从这里撕掉,这似乎是msgpack-c上的极少数资源之一。

任何人都可以指出我在正确的方向上“重新创建”电线另一侧的原始结构吗? 我发现实际使用反序列化数据的唯一方法是使用msgpack_object_print()调用从messagepack_object进行打印。 但这确实有效,所以我确定数据存在。

我是否需要以某种方式循环遍历序列化数据并使用带偏移量的msgpack_unpack_next()来检索每个someStruct成员? 将memcpy用于本地字节缓冲区?

任何帮助是极大的赞赏!

请在下面找到一个重写版本,说明如何打包/解压缩您的数据。

整个想法是以连续的方式打包结构的每个连续字段,并在解包时应用(当然)相同的逻辑。

在打包后,您可以按照自己的方式自由使用缓冲区(例如通过网络发送,保存在磁盘上等)。

 #include  #include  #include  typedef struct some_struct { uint32_t a; uint32_t b; float c; } some_struct; static char *pack(const some_struct *s, int num, int *size); static some_struct *unpack(const void *ptr, int size, int *num); /* Fixtures */ some_struct ary[] = { { 1234, 5678, 3.14f }, { 4321, 8765, 4.13f }, { 2143, 6587, 1.34f } }; int main(void) { /** PACK */ int size; char *buf = pack(ary, sizeof(ary)/sizeof(ary[0]), &size); printf("pack %zd struct(s): %d byte(s)\n", sizeof(ary)/sizeof(ary[0]), size); /** UNPACK */ int num; some_struct *s = unpack(buf, size, &num); printf("unpack: %d struct(s)\n", num); /** CHECK */ assert(num == (int) sizeof(ary)/sizeof(ary[0])); for (int i = 0; i < num; i++) { assert(s[i].a == ary[i].a); assert(s[i].b == ary[i].b); assert(s[i].c == ary[i].c); } printf("check ok. Exiting...\n"); free(buf); free(s); return 0; } static char *pack(const some_struct *s, int num, int *size) { assert(num > 0); char *buf = NULL; msgpack_sbuffer sbuf; msgpack_sbuffer_init(&sbuf); msgpack_packer pck; msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write); /* The array will store `num` contiguous blocks made of a, b, c attributes */ msgpack_pack_array(&pck, 3 * num); for (int i = 0; i < num; ++i) { msgpack_pack_uint32(&pck, s[i].a); msgpack_pack_uint32(&pck, s[i].b); msgpack_pack_float(&pck, s[i].c); } *size = sbuf.size; buf = malloc(sbuf.size); memcpy(buf, sbuf.data, sbuf.size); msgpack_sbuffer_destroy(&sbuf); return buf; } static some_struct *unpack(const void *ptr, int size, int *num) { some_struct *s = NULL; msgpack_unpacked msg; msgpack_unpacked_init(&msg); if (msgpack_unpack_next(&msg, ptr, size, NULL)) { msgpack_object root = msg.data; if (root.type == MSGPACK_OBJECT_ARRAY) { assert(root.via.array.size % 3 == 0); *num = root.via.array.size / 3; s = malloc(root.via.array.size*sizeof(*s)); for (int i = 0, j = 0; i < root.via.array.size; i += 3, j++) { s[j].a = root.via.array.ptr[i].via.u64; s[j].b = root.via.array.ptr[i + 1].via.u64; s[j].c = root.via.array.ptr[i + 2].via.dec; } } } msgpack_unpacked_destroy(&msg); return s; }