MsgPack Woes-析构函数、pack_raw_body等



我使用MsgPack作为为SOCI C++数据库访问API创建的自定义后端的一部分。最初,我的一些SOCI类将MsgPack::sbuffer对象作为成员变量,但我在SOCI对象的析构函数中遇到了一些问题——我认为这个问题与SOCI引用计数其某些对象的方式以及MsgPack对象的内存被多次释放有关。

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

请考虑以下(伪(代码片段。。。

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对象,并且发现文档/示例有点稀疏。如果人们能提供任何帮助,我们将不胜感激!

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);

如果我正确理解您的问题,您希望将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 

相关内容

  • 没有找到相关文章

最新更新