MessagePack Perl 到 C++ 反序列化

MessagePack Perl to C++ deserialisation

我是 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;
}

这会在 output_map 中生成一个 2 元素映射,但它只包含垃圾值 - 我的程序在 output_map.at()

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

我一直无法找到这个特定用例的任何示例,并且努力找出问题所在 - 这是序列化端的问题还是(似乎更有可能)反序列化端的问题?

编辑: 感谢@SinanÜnür 指出我的错误,我现在已经在问题中更新了。这不会改变散列被垃圾值填充的事实,因此无论搜索的键是什么,都会抛出相同的异常。

最终成功地结合了正确的二进制文件读取和对我们拥有的奇怪内部数据类型的一些修改,使其工作。

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