boost polymorphic XML serialization problem
Problem.
While serializing a class through a polymorphic pointer you get:
terminate called after throwing an instance of 'boost::archive::archive_exception' what(): unregistered class
Its because you didn’t use the BOOST_CLASS_EXPORT(MyClass) macro.
or:
/usr/local/include/boost-1_35/boost/archive/detail/iserializer.hpp: 589: error: no matching function for call to ‘load_wrapper(boost::archive::xml_iarchive&, const float&, boost::serialization::is_wrapper)’
Its because you made the serialize function const (or the load function). Remove the const keyword and it will work. I got this error when I copied and passed the save function renaming it to load (they were to be almost identical, so why type the same again). And that was the trap, cos the shown error doesn’t give a clue what could be wrong. After some time I got it working, the load function changes the object so it cannot be const! Not a very fortunate mistype, I had to spend some time figuring out what is happening.
Use this sample, and adapt it to your case:
#include <fstream>
#include <iostream>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/export.hpp>
class AbstractBase {
public:
virtual void base() = 0;
virtual ~AbstractBase() { }
};
BOOST_IS_ABSTRACT(AbstractBase)
class Derived1 : public AbstractBase {
friend class boost::serialization::access;
template<class Archive> void serialize(Archive & ar, const unsigned int version) {
boost::serialization::void_cast_register(
static_cast<Derived1 *>(NULL),
static_cast<AbstractBase *>(NULL)
);
ar & BOOST_SERIALIZATION_NVP(a1);
}
public:
float a1;
inline void base() { }
};
BOOST_CLASS_EXPORT(Derived1)
int main() {
AbstractBase* d1 = new Derived1();
std::ofstream ofs("filename.xml");
boost::archive::xml_oarchive oa(ofs);
oa << BOOST_SERIALIZATION_NVP(d1);
ofs.close();
return 0;
}
Nice article.
There is one more thing to note:
If the base class is in one dll and the derived class is in another, then one still gets “unregistered class” error, even if BOOST_CLASS_EXPORT macor is used.
Using static lib can fix this but the binary may be 10 times larger.