boost::serialization throwing “input stream error” on base class ptr XML serialization

Hello, This seems straight forward to me, but yet I'm stilling getting a input stream error and I don't understand why. The weird part about it is if I un-comment the serialization of the base class in my example it works, otherwise it does not. Here is the code: struct A { virtual ~A() {}; int i1 = 10; friend class boost::serialization::access; template <class Archive> void serialize(Archive& ar, const unsigned int version) { ar & make_nvp("int", i1); } }; struct B : A { virtual ~B() {}; float f1 = 5.0F friend class boost::serialization::access; template <class Archive> void serialize(Archive& ar, const unsigned int version) { ar & boost::serialization::base_object<A>(*this); ar & make_nvp("float", f1); } }; struct C : A { virtual ~C() {}; long l1 = 24; friend class boost::serialization::access; template <class Archive> void serialize(Archive& ar, const unsigned int version) { ar & boost::serialization::base_object<A>(*this); ar & make_nvp("long", l1); } }; //Why do these need to be wrappers?? namespace boost { namespace serialization { template<> struct is_wrapper : mpl::true_ {}; template<> struct is_wrapper<A> : mpl::true_ {}; template<> struct is_wrapper<const A> : mpl::true_ {}; } } BOOST_SERIALIZATION_ASSUME_ABSTRACT(A); BOOST_CLASS_EXPORT(B) BOOST_CLASS_EXPORT(C) int main(int argc, char** argv) { //A* a = new A(); A* b = new B(); A* c = new C(); //A* a1 = nullptr; A* a2 = nullptr; A* a3 = nullptr; ostringstream ostream; xml_oarchive oarchive(ostream); oarchive /*<< BOOST_SERIALIZATION_NVP(a)*/ << BOOST_SERIALIZATION_NVP(b) << BOOST_SERIALIZATION_NVP(c); istringstream istream(ostream.str()); xml_iarchive iarchive(istream); iarchive /*>> BOOST_SERIALIZATION_NVP(a1)*/ >> BOOST_SERIALIZATION_NVP(a2) >> BOOST_SERIALIZATION_NVP(a3); //delete a; delete b; delete c; //delete a1; delete a2; delete a3; } It's worth mentioning that this is with Boost 1.53 and GCC 4.8.0 w/ --std=c++11. The same code works fine in both cases worth the text and binary archives. I have tried changing the nvp's in the main to have the same key and in the input case no key, but I get the same error. Am I doing something wrong or is there an issue with the xml archive? Thanks, Jaime

hi think there's a problem with the way you are using BOOST_SERIALIZATION_NVP
macros. Because its xml you are saving in you need to specify the name
written and read to xml.
But now you are saving "b" and "c" to xml and reading for "a2" and "a3".
Use boost::serialization::make_nvp(name, var) instead to specify the name
written to the xml for the variables your trying to read/write. Or use same
c++ variable on read/write :)
like this:
ostringstream ostream;
xml_oarchive oarchive(ostream);
oarchive << BOOST_SERIALIZATION_NVP("TestVar1",a);
istringstream istream(ostream.str());
xml_iarchive iarchive(istream);
iarchive >> boost::serialization::make_nvp("TestVar1",a1);
On Wed, Apr 17, 2013 at 3:15 PM, jvetter
Hello,
This seems straight forward to me, but yet I'm stilling getting a input stream error and I don't understand why.
The weird part about it is if I un-comment the serialization of the base class in my example it works, otherwise it does not. Here is the code:
struct A { virtual ~A() {};
int i1 = 10;
friend class boost::serialization::access; template <class Archive> void serialize(Archive& ar, const unsigned int version) { ar & make_nvp("int", i1); } }; struct B : A { virtual ~B() {};
float f1 = 5.0F
friend class boost::serialization::access; template <class Archive> void serialize(Archive& ar, const unsigned int version) { ar & boost::serialization::base_**object<A>(*this); ar & make_nvp("float", f1); } }; struct C : A { virtual ~C() {};
long l1 = 24;
friend class boost::serialization::access; template <class Archive> void serialize(Archive& ar, const unsigned int version) { ar & boost::serialization::base_**object<A>(*this); ar & make_nvp("long", l1); } };
//Why do these need to be wrappers?? namespace boost { namespace serialization { template<> struct is_wrapper : mpl::true_ {}; template<> struct is_wrapper<A> : mpl::true_ {}; template<> struct is_wrapper<const A> : mpl::true_ {}; } }
BOOST_SERIALIZATION_ASSUME_**ABSTRACT(A); BOOST_CLASS_EXPORT(B) BOOST_CLASS_EXPORT(C)
int main(int argc, char** argv) { //A* a = new A(); A* b = new B(); A* c = new C(); //A* a1 = nullptr; A* a2 = nullptr; A* a3 = nullptr;
ostringstream ostream; xml_oarchive oarchive(ostream);
oarchive /*<< BOOST_SERIALIZATION_NVP(a)*/ << BOOST_SERIALIZATION_NVP(b) << BOOST_SERIALIZATION_NVP(c);
istringstream istream(ostream.str()); xml_iarchive iarchive(istream);
iarchive /*>> BOOST_SERIALIZATION_NVP(a1)*/ >> BOOST_SERIALIZATION_NVP(a2) >> BOOST_SERIALIZATION_NVP(a3);
//delete a; delete b; delete c; //delete a1; delete a2; delete a3; }
It's worth mentioning that this is with Boost 1.53 and GCC 4.8.0 w/ --std=c++11.
The same code works fine in both cases worth the text and binary archives. I have tried changing the nvp's in the main to have the same key and in the input case no key, but I get the same error.
Am I doing something wrong or is there an issue with the xml archive?
Thanks, Jaime
______________________________**_________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/**mailman/listinfo.cgi/boost-**usershttp://lists.boost.org/mailman/listinfo.cgi/boost-users

Jari wrote:
//Why do these need to be wrappers?? namespace boost { namespace serialization { template<> struct is_wrapper : mpl::true_ {}; template<> struct is_wrapper<A> : mpl::true_ {}; template<> struct is_wrapper<const A> : mpl::true_ {}; } }
I don't know why the above is there. It should be taken out
BOOST_SERIALIZATION_ASSUME_ABSTRACT(A); BOOST_CLASS_EXPORT(B) BOOST_CLASS_EXPORT(C)
int main(int argc, char** argv) { //A* a = new A(); A* b = new B(); A* c = new C(); //A* a1 = nullptr; A* a2 = nullptr; A* a3 = nullptr;
ostringstream ostream; xml_oarchive oarchive(ostream);
oarchive /*<< BOOST_SERIALIZATION_NVP(a)*/ << BOOST_SERIALIZATION_NVP(b) << BOOST_SERIALIZATION_NVP(c);
istringstream istream(ostream.str()); xml_iarchive iarchive(istream);
iarchive /*>> BOOST_SERIALIZATION_NVP(a1)*/ >> BOOST_SERIALIZATION_NVP(a2) >> BOOST_SERIALIZATION_NVP(a3);
//delete a; delete b; delete c; //delete a1; delete a2; delete a3; }
The problem is:
oarchive << BOOST_SERIALIZATION_NVP(a) creates an item data </a>
iarchive >> BOOST_SERIALIZATION_NVP(a1) expects an item
participants (3)
-
Jari
-
jvetter
-
Robert Ramey