-1

私はmessagepackを初めて使用し、perlでハッシュを取得し、messagepackを使用してシリアル化し、ファイルに書き込み、それをC ++コードに渡し、ファイルを読み取ってマップに逆シリアル化しようとしています。

ファイルを生成するための私のperlコードは次のとおりです(注-ファイルを読み込んでperlで正しく逆シリアル化できることを確認するために余分な部分を追加しましたが、実際にはこれを行う必要はありません):

#! perl

use strict;
use warnings;

use Data::MessagePack;

my %hTestHash = ('AAAAAA' => '20020101',
                 'BBBBBB' => '20030907');

my $packed = Data::MessagePack->pack(\%hTestHash);

open my $fh, '>', 'splodge.bin' or die "Failed to open slodge.bin for write: $!";
print $fh $packed;
close $fh;

open my $fh2, '<', 'splodge.bin' or die "Failed to open slodge.bin for read: $!";
local $/;
my $file = <$fh2>;

my $hrTest = Data::MessagePack->unpack($file);

次に、逆シリアル化する私の C++ コードは次のとおりです。

#include "msgpack.hpp"
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>

int main(void)
{
  // Deserialize the serialized data.
  std::ifstream ifs("splodge.bin", std::ifstream::in);
  std::stringstream buffer;
  buffer << ifs.rdbuf();
  msgpack::unpacked upd;
  msgpack::unpack(&upd, buffer.str().data(), buffer.str().size());
  msgpack::object obj = upd.get();
  std::map<std::string, std::string> output_map;
  msgpack::convert(output_map, obj);

  string date = output_map.at("AAAAAA");

  return 0;
}

これにより、 で 2 要素マップが生成さoutput_mapれますが、ガベージ値しか含まれていません - 私のプログラムは次のようにクラッシュしoutput_map.at()ます

{"▒▒▒▒▒▒"=>"▒▒▒▒▒▒▒▒", "▒▒▒▒▒▒"=>"▒▒▒▒▒▒▒▒"}
terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at
Aborted

この特定のユースケースの例を見つけることができず、何が問題なのかを確認するのに苦労しました.これはシリアライゼーションの終わりの問題ですか、それともデシリアライゼーションの終わりの問題ですか?

編集:私の間違いを指摘してくれた@SinanÜnürに感謝します。質問で更新しました。これは、ハッシュにガベージ値が入力されているという事実を変更しないため、検索対象のキーに関係なく同じ例外がスローされます。

4

1 に答える 1

-2

最後に、適切なバイナリ ファイルの読み取りと、私たちが持っている奇妙な社内データ型の変更を組み合わせて動作させることができました。

機能するコード (構造を に逆シリアル化しMap<string, msgpack::object>、必要に応じて各値を逆シリアル化する追加の手順が必要) は次のとおりです。

#include "msgpack.hpp"
#include "map.h"
#include <string>
#include <iostream>
#include <fstream>

void unpack_map(const msgpack::object& o, Map<string,msgpack::object>& results){
  ASSERT(o.type == msgpack::type::MAP);
  for (msgpack::object_kv *p = o.via.map.ptr, *pend = (o.via.map.ptr + o.via.map.size); p != pend; ++p)
    results[p->key.as<string>()] = p->val;
}

int main(void)
{
  streampos size;
  char * memblock;

  ifstream file ("splodge.bin", ios::in|ios::binary|ios::ate);
  if (file.is_open())
    {
      size = file.tellg();
      memblock = new char [size];
      file.seekg (0, ios::beg);
      file.read (memblock, size);
      file.close();

      cout << "the entire file content is in memory";
    }
  else cout << "Unable to open file";

  msgpack::unpacked upd;
  msgpack::unpack(&upd, memblock, size);
  msgpack::object obj = upd.get();

  if(obj.type != msgpack::type::MAP) {
    cout << ":(" << endl;
  } else {
    cout << ":)" << endl;
  }
  cout << "size: " << obj.via.map.size << endl;

  Map<string, msgpack::object> objectMap;
  unpack_map(obj, objectMap);

  msgpack::object val  = objectMap["BBBBBB"];
  string tmp = string(val.via.raw.ptr, val.via.raw.size);

  delete[] memblock;
  return 0;
}

tmp値を取る場所20030907

于 2016-12-14T17:51:06.710 に答える