最後に、多くの苦労の末、私はstd::map<int,map<int,structute values>
とiamが値をプリントすることができるシリアライズとデシリアライズ方法を発見しました。私たちは、シリアライズとdeserialiseの両方のために別々の機能をは、sstreamのboost binary_iarchiveを使ってシリアライズしてデシリアライズします
あなたは私が
以下のコードに関係している疑問を明確にしてくださいだろうが、直列化および
をdeserialisingの両方に使用
void serialize(archive & ar, const unsigned int version)
機能ですを持つことができます各クラスと構造体の中で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
なぜ分割ロード/セーブですか?実装は同じで、不必要なオーバーヘッドになります。 – sehe
@彼は彼が求めていると思っていました。つまり、質問2です。 –
"シリアライズとシリアル化の両方にvoid serialize(archive&ar、const unsigned int version)デシリアライジング " - 答えは"はい " – sehe