0

C++ データベース アクセス APIMsgPack用に作成しているカスタム バックエンドの一部として使用しています。当初、一部のクラスにはメンバー変数としてオブジェクトがありましたが、オブジェクトのデストラクタでいくつかの問題に遭遇しました。この問題は、参照がそのオブジェクトの一部をカウントする方法と、複数解放されるオブジェクトの基礎となるメモリに関連していると思います回。SOCISOCIMsgPack::sbufferSOCISOCIMsgPack

この問題を解決するために、MsgPack::sbufferメンバー変数をメンバー変数に置き換え、これらを使用してメソッドを使用して s をstd::vector<char>埋めることにしました。残念ながら、これにも問題があります。MsgPack::sbufferpack_raw_body

次の(疑似)コードスニペットを検討してください...

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 オブジェクトの操作方法を理解するのに苦労しているだけで、ドキュメントや例が少しまばらです。人々が提供できるどんな助けも大歓迎です!

4

2 に答える 2

0

あなたの質問を正しく理解できれば、データを生のバイナリ イメージとして 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 のコンストラクターは、すべてのベクター メンバーを 2 番目のパラメーターとして渡される同じ値で埋めます。

それは、次のドキュメントの (2) です。

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

この状況では、3 番目のコンストラクタである範囲バージョンを使用する必要があると思います。そのため、元のコードを修正したコードに置き換えました。

2 つ目の問題は、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 
于 2014-08-08T08:12:13.677 に答える
0

MsgPack API の癖の 1 つは、さまざまな 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);
于 2014-05-12T20:14:43.470 に答える