zoukankan      html  css  js  c++  java
  • 序列化库MessagePack应用(C++)

    介绍

    MessagePack(简称msgpack)是一个小巧而高效的序列化/反序列化库,支持多种开发语言。官方网站:http://msgpack.org/

    下面是官方的一个简介:

    It's like JSON.
    but fast and small.
    
    MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages 
    like JSON. But it's faster and smaller. Small integers are encoded into a single byte
    , and typical short
    strings require only one extra byte in addition to the strings themselves.

    msgpack支持非常多的开发语言,这篇随笔只讨论在C++代码中的调用。

    序列化键值对数据

    一个经常遇到的应用场景是,我们需要序列化一组键值对。这组键值对的大小是可变的,值类型也不确定,例如:

    key name  key type value type
    type string int
    ratio string double
    msg string string

    示例代码如下:

     1 /*
     2  * msgpack C++试验:序列化/反序列化大小可变的非标准map.
     3  * Author: 赵子清
     4  * Blog: http://www.cnblogs.com/zzqcn
     5  *
     6  * */
     7 
     8 
     9 #include <msgpack.hpp>
    10 #include <string>
    11 #include <cstring>
    12 #include <iostream>
    13 using namespace std;
    14 
    15 int main(int argc, char** argv)
    16 {
    17 
    18     msgpack::sbuffer  sbuf;
    19     msgpack::packer<msgpack::sbuffer>   pker(&sbuf);
    20 
    21     // 序列化
    22     pker.pack_map(3);
    23     pker.pack(string("type"));
    24     pker.pack(3);
    25     pker.pack(string("ratio"));
    26     pker.pack(2.15);
    27     pker.pack(string("msg"));
    28     pker.pack(string("hello world"));
    29 
    30     // 反序列化
    31     msgpack::unpacked  unpack;
    32     msgpack::unpack(&unpack, sbuf.data(), sbuf.size());
    33 
    34     // 直接输出结果
    35     msgpack::object  obj = unpack.get();
    36     cout << obj << endl;
    37 
    38     // 访问具体键值对
    39     msgpack::object_kv*  pkv;
    40     msgpack::object_kv*  pkv_end;
    41     msgpack::object      pk, pv;
    42     if(obj.via.map.size > 0)
    43     {
    44         pkv = obj.via.map.ptr;
    45         pkv_end = obj.via.map.ptr + obj.via.map.size;
    46 
    47         do
    48         {
    49             pk = pkv->key;
    50             pv = pkv->val;
    51             
    52             cout << pk << ", " << pv << endl;
    53 
    54             ++pkv;
    55         }
    56         while (pkv < pkv_end);
    57     }
    58 
    59     return 0;
    60 }

    输出结果:

    {"type"=>3, "ratio"=>2.15, "msg"=>"hello world"}
    "type", 3
    "ratio", 2.15
    "msg", "hello world"


     

    序列化自定义类型

    msgpack已支持了很多的标准类型,但有时我们会自己定义新的类型,这时,我们必须对新类型做某些修改,以使msgpack可以操作它。

    另外,如果你的类型中含有低层指针,则还需要进行一些处理,否则,msgpack只会进行浅拷贝,无法序列化指针所指向的内存数据。

    假设我们原本的类型如下:

    struct Foo
    {
        int  i;
        string  str;
        char*  data;
    };

    那么要让msgpack操作它,应修改为如下结构:

    struct Foo
    {
        int     i;
        string  str;
        // 原始指针类型,内部封装了pack_raw和pack_raw_body方法
        msgpack::type::raw_ref  data;
    
        MSGPACK_DEFINE(i, str, data); 
    };


    下面是完整示例代码:

     1 /*
     2  * msgpack C++试验:序列化/反序列化自定义数据结构.
     3  * Author: 赵子清
     4  * Blog: http://www.cnblogs.com/zzqcn
     5  * */
     6 
     7 
     8 #include <msgpack.hpp>
     9 #include <string>
    10 #include <cstring>
    11 #include <iostream>
    12 using namespace std;
    13 
    14 
    15 struct Foo
    16 {
    17     int     i;
    18     string  str;
    19     // 原始指针类型,内部封装了pack_raw和pack_raw_body方法
    20     msgpack::type::raw_ref  data;
    21 
    22     MSGPACK_DEFINE(i, str, data); 
    23 };
    24 
    25 
    26 int main(int argc, char** argv)
    27 {
    28     Foo  f;
    29     f.i = 4;
    30     f.str = "hello world";
    31     const char* tmp = "msgpack";
    32     f.data.ptr = tmp;
    33     f.data.size = strlen(tmp) + 1;
    34 
    35     msgpack::sbuffer  sbuf;
    36     msgpack::pack(sbuf, f);
    37 
    38     msgpack::unpacked  unpack;
    39     msgpack::unpack(&unpack, sbuf.data(), sbuf.size());
    40 
    41     msgpack::object  obj = unpack.get();
    42 
    43     Foo f2;
    44     obj.convert(&f2);
    45 
    46     cout << f2.i << ", " << f2.str << ", ";
    47     cout << f2.data.ptr << endl;
    48 
    49     return 0;
    50 }

     输出结果:

    4, hello world, msgpack
  • 相关阅读:
    FRAM在智能电子式电表中的应用
    element UI实现动态生成多级表头
    小微信小程序开发相关网站
    响应式开发bootstrap
    媒体查询
    前端导出功能实现的两种方式
    watch监听对象遇坑
    vue中使用v-for时为什么要用到key?为什么不能用index作为key?
    vue中我改变了data中的一个值,但现在视图上没有实时更新,请问我怎么拿到更新后的值?
    python 链接数据库的模块
  • 原文地址:https://www.cnblogs.com/zzqcn/p/3562512.html
Copyright © 2011-2022 走看看