我目前正试图在用C写的我使用msgpack序列化一个结构中,然后通过网络发送的内容为目的的项目中使用msgpack,和反序列化回在相应的结构另一边。
什么我想要做的浓缩版:
#include <stdio.h>
#include <msgpack.h>
#include <stdbool.h>
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 < 10 ; i++){
msgpack_pack_array (pck, 3);
msgpack_pack_uint32 (pck, structs[i].a);
msgpack_pack_uint32 (pck, structs[i].b);
msgpack_pack_float (pck, structs[i].c);
}
free(structs);
msgpack_packer_free(pck);
// Deserialize
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
bool deserialize_success = msgpack_unpack_next
(&msg, buff->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打印。 这不,但似乎工作,所以我敢肯定的数据是存在的。
我是否需要通过序列化的数据在某种程度上环路与偏移检索每个someStruct成员使用msgpack_unpack_next()? 使用的memcpy到本地字节的缓冲区?
任何帮助是极大的赞赏!
请从下面举例说明如何收拾/解压缩你的数据重写的版本。
整个想法就是收拾你的结构的每个连续的领域,以连续的方式,并应用(当然),同样的逻辑在解压缩时间。
包之后,您可以自由使用缓冲区你想要的方式(例如,通过网络发送,保存在磁盘上,等等)。
#include <stdio.h>
#include <assert.h>
#include <msgpack.h>
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;
}