
On Jul 9, 2006, at 15:02, Robert Ramey wrote:
without seeing the code I'm not sure what to day.
Double check that namespace in which save_construct_data is declared/defined.
the save/load construct_data code is all in boost::serialization. The declarations look like: in node.h: class Node { // normal stuff virtual ~Node(); virtual void some_function() = 0; private: template <class Archive> void serialize(Archive& ar, const unsigned int version); }; in simplenode.h: class SimpleNode : public Node { // normal stuff private: template <class Archive> void serialize(Archive& ar, const unsigned int version); }; in node.hh: BOOST_CLASS_TRACKING(Node, boost::serialization::track_always) BOOST_IS_ABSTRACT(Node) in simplenode.hh: BOOST_CLASS_TRACKING(CSimpleNode, boost::serialization::track_always) namespace boost { namespace serialization { template <class Archive> CORE_DATA_API void load_construct_data(Archive& ar, SimpleNode * sn, const unsigned int version); template <class Archive> CORE_DATA_API void save_construct_data(Archive& ar, const SimpleNode* sn, const unsigned int version); // I've also tried the save with all combinations of Node and SimpleNode, * and &, and const/nonconst. } } In another header (nodeset.h) I have: #include "node.h" class NodeSet { typedef std::vector<Node*> NodeVector; NodeVector m_nodes; // other stuff to make this useful private: template <class Archive> void serialize(Archive& ar, const unsigned int version); } template <class Archive> void register_my_types(Archive& ar); The definitions and template instantiations (for serialization) are in *.s.cpp. I'm not sure they're pertinent here, the compiler doesn't see them when it's dealing with the code that calls what's in the headers. in nodeset.s.cpp I have: #include <boost/archive/xml_oarchive.hpp> #include <boost/archive/xml_iarchive.hpp> #include <boost/serialization/ ... several serialization headers included> #include "node.hh" #include "simplenode.hh" template <class Archive> void NodeSet::serialize(Archive& ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(m_nodes); } template <class Archive> void register_my_types(Archive& ar) { ar.register_type(static_cast<SimpleNode*>(NULL)); ar.register_type(static_cast<NodeSet*>(NULL)); boost::serialization::void_cast_register<SimpleNode, Node>(NULL, NULL); } In the test (calling) code, I have: #include "node.hh" #include "simplenode.hh" std::string calling_function(NodeSet& ns) { std::ostringstream oss; boost::archive::xml_oarchive oar(oss); register_my_types(oar); oar << ns; std::string res = oss.str(); return str; } There's other code for readback, but it (so far) appears to be ok. There's obviously a LOT of actual detail missing, but I think I've included the essential bits. My actual test case is slightly more complex, as it includes several other classes - however, I have already gotten THOSE classes to properly serialize. I only ran into the problem when I added the Node and SimpleNode classes (NodeSet is actually represented by a different class, but it holds an m_nodes member exactly as shown here. I'd include more, but what with my other cruft and classes, my current test case is actually over 2000 lines... But again, I only ran into the problem with the addition of the above Node and SimpleNode classes.
I have a structure I'm trying to serialize that contains an STL vector of pointers to an abstract base type. When I serialize it, the save_construct_data free function is NOT called - the inline default version is always used. On de-serializing, the load_construct_data IS called! but, of course, fails because the data for it isn't there (although it throws archive_exception(archive_exception::unregistered_class) when it fails).