c++ - boost serialiaze input stream error -
i working on simple serialization class. keep throwing exception on input stream. have put below example of attempting accomplish in simple terms.
i have simple example of boost serialization getting exception on:
#include <boost/serialization/serialization.hpp> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/export.hpp> #define nvp(x) x class base { public: friend class boost::serialization::access; base (){ v1 = 10;} int v1; template<class archive> void serialize(archive & ar, const unsigned int file_version) { ar & nvp(v1); } virtual void bla()=0; }; class derived : public base { public: friend class boost::serialization::access; int v2 ; derived() { v2 = 100;} template<class archive> void serialize(archive & ar, const unsigned int file_version){ boost::serialization::base_object<base>(* this); ar & nvp(v2); } virtual void bla(){}; }; boost_class_export(base); boost_class_export_guid(derived, "derived"); int main ( ) { std::stringstream ss; boost::archive::text_oarchive ar(ss); base *b = new derived(); ar << nvp(b); std::cout << ss.str()<<std::endl; std::istringstream ssi; base *b1 = new derived(); { boost::archive::text_iarchive ar1(ssi); ar1 >> b1; } //std::cout << ssi.str(); std::cout << "v1: " << b1->v1 << std::endl; }
the exception getting is:
terminate called after throwing instance of 'boost::archive::archive_exception' what(): input stream error
any appreciated.
you're reading empty stream:
std::istringstream ssi; // ... boost::archive::text_iarchive ar1(ssi);
also, leak object:
base *b1 = new derived();
here's fixed example, notes:
- it's practice/important close archives before using streamed data
boost_class_export_guid(derived, "derived")
doesn't add beyondboost_class_export(derived)
you can print v2 conditionally:
if (auto* d = dynamic_cast<derived*>(b1)) std::cout << "v2: " << d->v2 << std::endl;
i've used
bla()
example print values insteadnvp()
bit iffy there. why not leave out non-tagged archives (ie. other xml)? if intend support xml, useboost_serialization_nvp
,boost::serialization::make_nvp
etc.std::cout << "v2: " << b1->v2 << std::endl;
out of placejust initialize
b1
null don't leak it; remember free pointers (use smart pointers!)the mix of
public:
,friend
in types didn't mean much
#include <boost/serialization/serialization.hpp> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/export.hpp> #include <sstream> class base { public: base(int v1) : v1(v1) {} virtual void bla() const = 0; private: friend class boost::serialization::access; template <class archive> void serialize(archive &ar, unsigned /*int const file_version*/) { ar & boost_serialization_nvp(v1); } protected: int v1; }; class derived : public base { public: derived(int v1 = 10, int v2 = 100) : base(v1), v2(v2) {} virtual void bla() const { std::cout << "v1: " << v1 << ", v2: " << v2 << "\n"; } private: friend class boost::serialization::access; int v2; template <class archive> void serialize(archive &ar, unsigned /*int const file_version*/) { boost::serialization::base_object<base>(*this); ar & boost_serialization_nvp(v2); } }; boost_class_export(base) boost_class_export(derived) int main() { std::stringstream ss; { boost::archive::text_oarchive ar(ss); base *b = new derived(); ar << boost::serialization::make_nvp("base", b); delete b; // todo use raii instead } std::cout << ss.str() << std::endl; base *deserialized = nullptr; { boost::archive::text_iarchive ar1(ss); ar1 >> boost::serialization::make_nvp("base", deserialized); } deserialized->bla(); delete deserialized; }
prints
22 serialization::archive 12 0 7 derived 1 0 0 100 v1: 10, v2: 100
Comments
Post a Comment