2017-03-28 18 views
0

最後に、多くの苦労の末、私はstd::map<int,map<int,structute values>とiamが値をプリントすることができるシリアライズとデシリアライズ方法を発見しました。私たちは、シリアライズとdeserialiseの両方のために別々の機能をは、sstreamのboost binary_iarchiveを使ってシリアライズしてデシリアライズします

あなたは私が

  1. 以下のコードに関係している疑問を明確にしてくださいだろうが、直列化および

  2. をdeserialisingの両方に使用void serialize(archive & ar, const unsigned int version)機能ですを持つことができます各クラスと構造体の中で

  3. xmlの作成にも同じ機能を利用できますか、それともすてきですかXML

#include <boost/archive/binary_oarchive.hpp> 
#include <boost/archive/binary_iarchive.hpp> 
#include <boost/serialization/binary_object.hpp> 
#include <boost/serialization/serialization.hpp> 
#include <iostream> 
#include <string> 
#include <iomanip> 
#include <sstream> 
#include <map> 
#include <boost/serialization/map.hpp> 

struct values 
{ 
    std::string name; 
    std::string sex; 
    values():name("dummy"),sex("dummy"){} ; 
    template<class archive> 
    void serialize(archive & ar, const unsigned int version) 
    { 
     ar & name ; 
     ar & sex ; 
    } 
}; 
class Myclass 
{ 
public: 

    Myclass() 
    { 
    values val1; 
    e_group.insert(std::make_pair(1,val1)) ; 
    e_group.insert(std::make_pair(2,val1)) ; 
    p_group.insert(std::make_pair(1,e_group)) ; 
    p_group.insert(std::make_pair(2,e_group)) ; 
    } 
    template<class archive> 
    void serialize(archive & ar, const unsigned int version) 
    { 
    ar & e_group ; 
    ar & p_group; 
    } 
    typedef std::map<int,values> groups; 
    typedef std::map<int,groups> Pgroups; 
    groups e_group; 
    Pgroups p_group; 
}; 

int main() { 
    char buf[256]; 

    Myclass obj; 

    std::stringstream os(std::ios_base::binary| std::ios_base::out| std::ios_base::in); 
    { 
     boost::archive::binary_oarchive oa(os, boost::archive::no_header); 
     oa << obj ; 
     // oa << make_binary_object(&e_group, sizeof(e_group)); 
    } 

    //print binary data 
    std::string data = os.str(); 
    for (uint8_t ch : data) { 
     std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(ch) << " "; 
    } 



    Myclass t2; 
    {  
     memcpy(buf, os.str().data(), os.str().length()); 
     if(memcmp(buf, os.str().data(), os.str().length()) != 0) 
      printf("memcpy error\n"); 
     std::stringstream is(std::string(buf, buf+os.str().length()), std::ios_base::binary| std::ios_base::out| std::ios_base::in); 
     boost::archive::binary_iarchive ia(is, boost::archive::no_header); 
     ia >> t2; 
    } 

    for(auto &i:t2.p_group){ 
     std::cout<<"\n"<<i.first<<"\n"; 
     for(auto &j:i.second){ 
      std::cout<<"\t"<<j.first<<"\t"<<j.second.name<<"\t"<<j.second.sex<<"\n"; 
     } 
    } 
    return 0; 
} 

のために別々のシリアライズとdeserialise機能を持つ方法は、アップデート:私はリチャードのコードを更新してコンパイルされたバイナリ

#include <boost/archive/binary_oarchive.hpp> 
#include <boost/archive/xml_oarchive.hpp> 
#include <boost/archive/binary_iarchive.hpp> 
#include <boost/serialization/binary_object.hpp> 
#include <boost/serialization/serialization.hpp> 
#include <boost/serialization/nvp.hpp> 
#include <iostream> 
#include <string> 
#include <iomanip> 
#include <sstream> 
#include <fstream> 

#include <map> 
#include <boost/serialization/map.hpp> 
#include <boost/serialization/split_member.hpp> 


struct values 
{ 
    std::string name; 
    std::string sex; 
    values():name("dummy"),sex("dummy"){} ; 

    BOOST_SERIALIZATION_SPLIT_MEMBER(); 

    template<class Archive> 
    void save(Archive & ar, const unsigned int version) const 
    { 
     // note, version is always the latest when saving 
     ar & BOOST_SERIALIZATION_NVP(name); 
     ar & BOOST_SERIALIZATION_NVP(sex); 
    } 
    template<class Archive> 
    void load(Archive & ar, const unsigned int version) 
    { 
     ar & BOOST_SERIALIZATION_NVP(name); 
     ar & BOOST_SERIALIZATION_NVP(sex); 
    } 
}; 
class Myclass 
{ 
public: 

    Myclass() 
    { 
     values val1; 
     e_group.insert(std::make_pair(1,val1)) ; 
     e_group.insert(std::make_pair(2,val1)) ; 
     p_group.insert(std::make_pair(1,e_group)) ; 
     p_group.insert(std::make_pair(2,e_group)) ; 
    } 

    BOOST_SERIALIZATION_SPLIT_MEMBER(); 

    template<class Archive> 
    void save(Archive & ar, const unsigned int version) const 
    { 
     // note, version is always the latest when saving 
     ar & BOOST_SERIALIZATION_NVP(e_group); 
     ar & BOOST_SERIALIZATION_NVP(p_group); 
    } 
    template<class Archive> 
    void load(Archive & ar, const unsigned int version) 
    { 
     ar & BOOST_SERIALIZATION_NVP(e_group); 
     ar & BOOST_SERIALIZATION_NVP(p_group); 
    } 

    typedef std::map<int,values> groups; 
    typedef std::map<int,groups> Pgroups; 
    groups e_group; 
    Pgroups p_group; 
}; 

template<class Archive, class Object> 
std::string serialise_to_string(Object const& assetlist) 
{ 
    auto os = std::ostringstream(std::ios::binary); 
    Archive arch { os, boost::archive::no_header }; 
    arch << BOOST_SERIALIZATION_NVP(assetlist); 
    return os.str(); 
}; 


std::ostream& dump(std::ostream& os, std::string const& s) 
{ 
    const char *sep = ""; 
    for (uint8_t ch : s) { 
     std::cout << sep << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(ch); 
     sep = " "; 
    } 
    return os; 
} 

template<class Archive , class Object> 
void deserialise_to_obj(std::string const &s1,Object &outObj) 
{ 
    std::stringstream is(s1, std::ios_base::binary| std::ios_base::out| std::ios_base::in); 
    Archive arch { is, boost::archive::no_header }; 
    arch >> BOOST_SERIALIZATION_NVP(outObj); 
}; 


int main() { 

    Myclass obj ; 
    std::string s1 = serialise_to_string<boost::archive::binary_oarchive>(obj); 
    dump(std::cout, s1) << std::endl << std::endl; 

    auto s2 = serialise_to_string<boost::archive::xml_oarchive>(obj); 

    //Save xml to a file 
    std::ofstream ofs("output.xml"); 
    ofs << s2 << std::endl << std::endl; 

    //Deserialize the binary data to object 
    Myclass outObj; 
    deserialise_to_obj<boost::archive::binary_iarchive>(s1,outObj); 

    //Print the object 
    for(auto &i:outObj.p_group){ 
     std::cout<<"\n"<<i.first<<"\n"; 
     for(auto &j:i.second){ 
      std::cout<<"\t"<<j.first<<"\t"<<j.second.name<<"\t"<<j.second.sex<<"\n"; 
     } 
    } 
} 

コードをdeserilaizeする機能を追加しました使用方法coliru

お勧めします。私のアプローチが間違っている場合にアドバイスしてください。

@seheと@richardに感謝したいと思います。単なる文字列の4つの別々のコピーを作成しています

memcpy(buf, os.str().data(), os.str().length()); 
    if(memcmp(buf, os.str().data(), os.str().length()) != 0) 

おかげ Tejas

答えて

2

まず、これをしません。今

質問:

が無効にserializeです(アーカイブ& AR、のconst unsigned int型バージョン)機能の両方直列化のために使用してはい

は、我々が持っていることができますdeserialising各クラスと構造体のシリアル化とデシリアライズのための別々の関数

はい

あなたが欲しいはい

同じ機能もXMLを作成するために利用することができ、またはそれは、XML

のために別々のシリアライズとdeserialise機能を持っているきちんとした方法でありますxml_oarchiveおよびマクロBOOST_SERIALIZATION_SPLIT_MEMBERおよびBOOST_SERIALIZATION_NVP

#include <boost/archive/binary_oarchive.hpp> 
#include <boost/archive/xml_oarchive.hpp> 
#include <boost/archive/binary_iarchive.hpp> 
#include <boost/serialization/binary_object.hpp> 
#include <boost/serialization/serialization.hpp> 
#include <boost/serialization/nvp.hpp> 
#include <iostream> 
#include <string> 
#include <iomanip> 
#include <sstream> 
#include <map> 
#include <boost/serialization/map.hpp> 
#include <boost/serialization/split_member.hpp> 


struct values 
{ 
    std::string name; 
    std::string sex; 
    values():name("dummy"),sex("dummy"){} ; 

    BOOST_SERIALIZATION_SPLIT_MEMBER(); 

    template<class Archive> 
    void save(Archive & ar, const unsigned int version) const 
    { 
     // note, version is always the latest when saving 
     ar & BOOST_SERIALIZATION_NVP(name); 
     ar & BOOST_SERIALIZATION_NVP(sex); 
    } 
    template<class Archive> 
    void load(Archive & ar, const unsigned int version) 
    { 
     ar & BOOST_SERIALIZATION_NVP(name); 
     ar & BOOST_SERIALIZATION_NVP(sex); 
    } 
}; 
class Myclass 
{ 
public: 

    Myclass() 
    { 
     values val1; 
     e_group.insert(std::make_pair(1,val1)) ; 
     e_group.insert(std::make_pair(2,val1)) ; 
     p_group.insert(std::make_pair(1,e_group)) ; 
     p_group.insert(std::make_pair(2,e_group)) ; 
    } 

    BOOST_SERIALIZATION_SPLIT_MEMBER(); 

    template<class Archive> 
    void save(Archive & ar, const unsigned int version) const 
    { 
     // note, version is always the latest when saving 
     ar & BOOST_SERIALIZATION_NVP(e_group); 
     ar & BOOST_SERIALIZATION_NVP(p_group); 
    } 
    template<class Archive> 
    void load(Archive & ar, const unsigned int version) 
    { 
     ar & BOOST_SERIALIZATION_NVP(e_group); 
     ar & BOOST_SERIALIZATION_NVP(p_group); 
    } 

    typedef std::map<int,values> groups; 
    typedef std::map<int,groups> Pgroups; 
    groups e_group; 
    Pgroups p_group; 
}; 

template<class Archive, class Object> 
std::string serialise_to_string(Object const& o) 
{ 
    auto os = std::ostringstream(std::ios::binary); 
    Archive arch { os, boost::archive::no_header }; 
    arch << BOOST_SERIALIZATION_NVP(o); 
    return os.str(); 
}; 

std::ostream& dump(std::ostream& os, std::string const& s) 
{ 
    const char *sep = ""; 
    for (uint8_t ch : s) { 
     std::cout << sep << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(ch); 
     sep = " "; 
    } 
    return os; 
} 

int main() { 
    char buf[256]; 

    Myclass obj; 

    auto s1 = serialise_to_string<boost::archive::binary_oarchive>(obj); 
    dump(std::cout, s1) << std::endl << std::endl; 

    auto s2 = serialise_to_string<boost::archive::xml_oarchive>(obj); 
    std::cout<< s2 << std::endl << std::endl; 

    return 0; 
} 

出力例:

00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 02 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 02 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 02 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 02 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 

<o class_id="0" tracking_level="0" version="0"> 
    <e_group class_id="1" tracking_level="0" version="0"> 
     <count>2</count> 
     <item_version>0</item_version> 
     <item class_id="2" tracking_level="0" version="0"> 
      <first>1</first> 
      <second class_id="3" tracking_level="0" version="0"> 
       <name>dummy</name> 
       <sex>dummy</sex> 
      </second> 
     </item> 
     <item> 
      <first>2</first> 
      <second> 
       <name>dummy</name> 
       <sex>dummy</sex> 
      </second> 
     </item> 
    </e_group> 
    <p_group class_id="4" tracking_level="0" version="0"> 
     <count>2</count> 
     <item_version>0</item_version> 
     <item class_id="5" tracking_level="0" version="0"> 
      <first>1</first> 
      <second> 
       <count>2</count> 
       <item_version>0</item_version> 
       <item> 
        <first>1</first> 
        <second> 
         <name>dummy</name> 
         <sex>dummy</sex> 
        </second> 
       </item> 
       <item> 
        <first>2</first> 
        <second> 
         <name>dummy</name> 
         <sex>dummy</sex> 
        </second> 
       </item> 
      </second> 
     </item> 
     <item> 
      <first>2</first> 
      <second> 
       <count>2</count> 
       <item_version>0</item_version> 
       <item> 
        <first>1</first> 
        <second> 
         <name>dummy</name> 
         <sex>dummy</sex> 
        </second> 
       </item> 
       <item> 
        <first>2</first> 
        <second> 
         <name>dummy</name> 
         <sex>dummy</sex> 
        </second> 
       </item> 
      </second> 
     </item> 
    </p_group> 
</o> 
+0

なぜ分割ロード/セーブですか?実装は同じで、不必要なオーバーヘッドになります。 – sehe

+0

@彼は彼が求めていると思っていました。つまり、質問2です。 –

+0

"シリアライズとシリアル化の両方にvoid serialize(archive&ar、const unsigned int version)デシリアライジング " - 答えは"はい " – sehe

関連する問題