MessagePack Perl到C ++反序列化

时间:2016-12-02 15:09:41

标签: c++ perl msgpack messagepack

我是messagepack的新手,我正在尝试在perl中使用哈希,使用messagepack将其序列化,将其写入文件,将其传递给c ++代码,在该代码中读取文件并将其反序列化为映射。 / p>

我生成文件的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指出我的错误,我现在已在问题中更新了。这并没有改变哈希值被垃圾值填充的事实,因此无论搜索的密钥是什么,都会抛出相同的异常。

1 个答案:

答案 0 :(得分:-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