2016-12-02 31 views
0

我是新來的messagepack,我試圖在perl中使用散列,使用messagepack將其序列化,將其寫入文件,並將其傳遞給讀取和反序列化文件的C++代碼進入地圖。MessagePack Perl到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.at()

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

我一直無法找到這個特定用例的任何例子,並努力查看出了什麼問題 - 這是序列化結束時的問題還是(更可能)在反序列化結束?

編輯:感謝@SinanÜnür指出我的錯誤,我現在已經更新的問題。這不會改變散列填充垃圾值的事實,因此無論搜索到什麼密鑰,都會拋出相同的異常。

+0

@SinanÜnür感謝,看到我上面編輯 – rbennett485

+0

@SinanÜnür,所以這個相同的代碼爲你工作正常,並在C++中生成一個地圖? – rbennett485

+0

''''和''''應該是'':raw''和''<:raw'',特別是如果你在Windows機器上。同樣,C++程序應該將流設置爲二進制。 – ikegami

回答

-2

最後設法使它與正確的二進制文件讀取和我們有的奇怪的內部數據類型的一些munning的組合工作。

運作代碼(反序列化結構成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