-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 元素映射 in 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

终于设法让它与正确的二进制文件读取和一些我们拥有的奇怪的内部数据类型的组合一起工作。

功能代码(将结构反序列化为 a 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 回答