【问题标题】:MsgPack Woes - Destructor, pack_raw_body, EtcMsgPack Woes - 析构函数,pack_raw_body 等
【发布时间】:2014-04-29 14:30:10
【问题描述】:

我使用MsgPack 作为我为SOCI C++ database access API 创建的自定义后端的一部分。最初,我的一些SOCI 类将MsgPack::sbuffer 对象作为成员变量,但我在SOCI 对象的析构函数中遇到了一些问题——我相信问题与SOCI 引用计数的方式有关它的对象和作为MsgPack 对象基础的内存被多次释放。

为了解决这个问题,我决定将MsgPack::sbuffer 成员变量替换为std::vector<char> 成员变量,并使用pack_raw_body 方法使用它们来填充MsgPack::sbuffers。不幸的是,我也遇到了麻烦。

请考虑以下(伪)代码 sn-p...

msgpack::sbuffer buf1;
msgpack::packer<msgpack::sbuffer> bufPkr1(&buf1);
bufPkr1.pack_array(num);
for (int ndx = 0; ndx < num; ++ndx) {
  bufPkr1.pack_array(3);
  bufPkr1.pack(std::string("foo"));
  bufPkr1.pack(std::string("bar"));
  bufPrk1.pack(221);
}

std::vector<char> chrVct = std::vector<char>(buf1.size(), *buf1.data());

msgpack::unpacked unPkd1;
msgpack::unpack(&unPkd1, buf1.data(), buf1.size());

msgpack::object toStr1 = unPkd1.get();
std::cout << "MsgPack1: " << toStr1 << std::endl;

msgpack::sbuffer buf2;
msgpack::packer<msgpack::sbuffer> bufPkr2(&buf2);
bufPkr1.pack_raw(chrVct.size());
bufPkr1.pack_raw_body(chrVct.data(), chrVct.size());

msgpack::unpacked unPkd2;
msgpack::unpack(&unPkd2, buf2.data(), buf2.size());

msgpack::object toStr2 = unPkd2.get();
std::cout << "MsgPack2: " << toStr2 << std::endl;

输出...

MsgPack1: [["foo", "bar", 221], ["foo", "bar", 221], ["foo", "bar", 221],..., ["foo", "bar", 221]]
MsgPack2: ""

一般来说,我只是无法弄清楚如何使用 MsgPack 对象,并且发现文档/示例有点稀疏。人们可以提供的任何帮助将不胜感激!

【问题讨论】:

    标签: c++ msgpack soci


    【解决方案1】:

    MsgPack API 的一个怪癖似乎与各种 MsgPack 对象的生命周期有关,以及被打包 MsgPack 对象的对象/整体数据类型。

    如果我遵循这个习语,上面的代码可能会更好......

    msgpack::sbuffer buf1;
    msgpack::packer<msgpack::sbuffer> bufPkr1(&buf1);
    bufPkr1.pack_array(num);
    for (int ndx = 0; ndx < num; ++ndx) {
      bufPkr1.pack_array(3);
      bufPkr1.pack(std::string("foo"));
      bufPkr1.pack(std::string("bar"));
      bufPrk1.pack(221);
    }
    
    msgpack::unpacked unPkd1;
    msgpack::unpack(&unPkd1, buf1.data(), buf1.size());
    const msgpack::object obj1 = respUnPk.get();
    
    msgpack::sbuffer buf2;
    msgpack::packer<msgpack::sbuffer> bufPkr2(&buf2);
    bufPkr2.pack(obj1);
    

    【讨论】:

      【解决方案2】:

      如果我正确理解您的问题,您希望将 buf1 中的数据打包为原始二进制图像。然后你想解压它。

      第一个问题是 std::vector 的构造函数的使用。请参阅以下代码中的注释 P1:

      #include <msgpack.hpp>
      #include <iostream>
      #include <iomanip>
      #include <algorithm>
      
      int main() {
          int const num = 5;
          msgpack::sbuffer buf1;
          msgpack::packer<msgpack::sbuffer> bufPkr1(&buf1);
          bufPkr1.pack_array(num);
          for (int ndx = 0; ndx < num; ++ndx) {
              bufPkr1.pack_array(3);
              bufPkr1.pack(std::string("foo"));
              bufPkr1.pack(std::string("bar"));
              bufPkr1.pack(221);
          }
      
      // P1
      //  std::vector<char> chrVct = std::vector<char>(buf1.size(), *buf1.data());
          std::vector<char> chrVct = std::vector<char>(buf1.data(), static_cast<char*>(buf1.data()) + buf1.size());
      
          msgpack::unpacked unPkd1;
          msgpack::unpack(&unPkd1, buf1.data(), buf1.size());
      
          msgpack::object toStr1 = unPkd1.get();
          std::cout << "MsgPack1: " << toStr1 << std::endl;
      
          msgpack::sbuffer buf2;
          msgpack::packer<msgpack::sbuffer> bufPkr2(&buf2);
      
      // P2
      //  bufPkr1.pack_raw(chrVct.size());
      //  bufPkr1.pack_raw_body(chrVct.data(), chrVct.size());
          bufPkr2.pack_raw(chrVct.size());
          bufPkr2.pack_raw_body(chrVct.data(), chrVct.size());
      
          msgpack::unpacked unPkd2;
          msgpack::unpack(&unPkd2, buf2.data(), buf2.size());
      
          msgpack::object toStr2 = unPkd2.get();
          std::cout << "MsgPack2: " << toStr2.via.raw.size << std::endl;
          std::for_each(toStr2.via.raw.ptr, toStr2.via.raw.ptr+toStr2.via.raw.size,
                  [](char e) {
                      std::cout << std::hex << std::setw(2) << std::setfill('0') << (static_cast<int>(e) & 0xff) << ' ';
                  });
          std::cout << std::endl;
      }
      

      原代码中std::vector的构造函数是将所有vector成员填充为作为第二个参数传递的相同值。

      即以下文档中的(2):

      http://www.cplusplus.com/reference/vector/vector/vector/

      我认为在这种情况下应该使用第三个构造函数,范围版本。所以我用修改后的代码替换了原来的代码。

      第二个问题是从未使用过bufPkr2。我想这只是错字。我把原来的代码注释掉了,替换掉了。

      作为这些修改的结果,我得到了以下结果:

      MsgPack1: [["foo", "bar", 221], ["foo", "bar", 221], ["foo", "bar", 221], ["foo", "bar", 221], ["foo", "bar", 221]]
      MsgPack2: 56
      95 93 a3 66 6f 6f a3 62 61 72 cc dd 93 a3 66 6f 6f a3 62 61 72 cc dd 93 a3 66 6f 6f a3 62 61 72 cc dd 93 a3 66 6f 6f a3 62 61 72 cc dd 93 a3 66 6f 6f a3 62 61 72 cc dd 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-02
        • 1970-01-01
        • 2013-07-07
        • 2018-03-22
        • 2014-05-27
        • 2011-04-16
        • 2011-04-03
        相关资源
        最近更新 更多