
Robert Ramey wrote:
The real question here is:
What else is supposed to be in this file? Do I need to put in the code that loads and saves archives in this file?
And here is the answer.
I expect that BOOST_CLASS_EXPORT will be specified in the same header file as the class declaration to which it corresponds. That is, BOOST_CLASS_EXPORT(T) is a "trait" of the class. This trait is the "external name" used to identify the class and is needed when serializing polymorphic types through a base class pointer.
I expect that one's program will generally look like:
#include <boost/archive/xml_oarchive.hpp> .... #include "my_class.hpp" // which has BOOST_CLASS_EXPORT inside
In boost 1.35 (aka HEAD) these headers can be in any order. In 1.34 and earlier, the archive headers have to go before any headers which contain BOOST_CLASS_EXPORT
Robert, First, thank you very much for taking the time to answer my clueless questions. Second, I'm not sure what I get when I check out the boost files using CVS, as instructed in the "Getting Started" section of the web site. Do I have "HEAD" this way? If not, how do I get it? Third, here is some code that reproduces my error. I'm sorry if it's a bit overly complicated; I just don't know what exactly is causing the error. #include <boost/archive/xml_oarchive.hpp> #include <boost/archive/xml_iarchive.hpp> #include <boost/serialization/nvp.hpp> #include <fstream> template <class ObjectType> void save(const ObjectType& object, const char* filename) { std::ofstream ofs(filename); assert(ofs.good()); boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(object); } template <class ObjectType> void load(ObjectType& object, const char* filename) { std::ifstream ifs(filename); assert(ifs.good()); boost::archive::xml_iarchive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(object); } namespace A { namespace B { namespace C { struct Base { int type; virtual ~Base() {} }; struct Point :Base { double x; }; } } } #include <boost/serialization/export.hpp> namespace boost { namespace serialization { using namespace A::B; template<class Archive> void serialize(Archive& ar, C::Base& x, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(x.type); } template<class Archive> void serialize(Archive& ar, C::Point& x, const unsigned int version) { ar & make_nvp("Base", base_object<C::Base>(x)); ar & BOOST_SERIALIZATION_NVP(x.x); } } } namespace A { namespace B { namespace C { BOOST_CLASS_EXPORT(Point); } } } #include <boost/shared_ptr.hpp> #include <list> namespace A { namespace B { namespace C { struct Line :Base { struct Item { bool flop; boost::shared_ptr<Base> ptr; }; double slope; double intercept; std::list<Item> items; }; } struct Object { struct Item { bool flip; boost::shared_ptr<C::Base> ptr; }; std::list<Item> items; }; } } #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/export.hpp> namespace boost { namespace serialization { using namespace A::B; template<class Archive> void serialize(Archive& ar, C::Line::Item& x, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(x.flop); ar & BOOST_SERIALIZATION_NVP(x.ptr); } template<class Archive> void serialize(Archive& ar, C::Line& x, const unsigned int version) { ar & make_nvp("Security", base_object<C::Base>(x)); ar & BOOST_SERIALIZATION_NVP(x.items); } template<class Archive> void serialize(Archive& ar, Object::Item& x, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(x.flip); ar & BOOST_SERIALIZATION_NVP(x.ptr); } template<class Archive> void serialize(Archive& ar, Object& x, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(x.items); } } } namespace A { namespace B { namespace C { BOOST_CLASS_EXPORT(Line) } } } namespace A { namespace B { void Load(Object& object, const char* filename); void Save(const Object& object, const char* filename); void Load(Object& object, const char* filename) { load(object, filename); } void Save(const Object& object, const char* filename) { save(object, filename); } } }