MessagePack(簡稱msgpack)是一個小巧而高效的序列化/反序列化庫,支持多種開發語言。官方網站:http://msgpack.org/ 。ios
下面是官方的一個簡介:數據結構
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++代碼中的調用。網站
一個常常遇到的應用場景是,咱們須要序列化一組鍵值對。這組鍵值對的大小是可變的,值類型也不肯定,例如:ui
key name | key type | value type |
type | string | int |
ratio | string | double |
msg | string | string |
示例代碼以下:spa
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能夠操做它。code
另外,若是你的類型中含有低層指針,則還須要進行一些處理,不然,msgpack只會進行淺拷貝,沒法序列化指針所指向的內存數據。orm
假設咱們本來的類型以下:blog
struct Foo { int i; string str; char* data; };
那麼要讓msgpack操做它,應修改成以下結構:ip
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 |