마지막으로 많은 어려움을 겪은 후 std::map<int,map<int,structute values>
을 직렬화 및 비 직렬화하여 iam이 값을 인쇄 할 수있는 방법을 찾았습니다.sstream에서 boost binary_iarchive를 사용하여 직렬화 및 역 직렬화
당신은 내가
-
아래의 코드에 관한 한 의심을 명확히 주시겠습니까은
void serialize(archive & ar, const unsigned int version)
모두 serialising에 사용되는 기능과 deserialising가 우리는 직렬화를하고 deserialise 모두 별도의 기능을 가질 수 각 클래스 및 구조체에서
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가 부스트를 도와 준 것에 감사드립니다.
감사 테자스
왜 분할로드/저장? 구현은 동일하므로 불필요한 오버 헤드가 발생합니다. – sehe
@ 그가 물었던 것 같아요. 질문 2입니다. –
그는 "serialize (archive & ar, const unsigned int version) 함수가 직렬화 및 deserialising "- 대답은"예 "입니다. – sehe