In your test case you serialize SimpleNode instance
rather than a pointer. So I would ne expect
save_construct_data to be called in this case.
A couple of things don't look right to me.
a0 Node has a serialize function. But the program
also includes
boost::serialization::void_cast_register
NULL);
which I believe should be necessary only if the SimpleNode serialize function doesn't invoke base_object ... b) Of course I'm wondering what CORE_DATA_API might expand to - and if this might prevent the compiler from finding the specializaton. Robert Ramey Hubert Hoover wrote:
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
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
#include #include
#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
(NULL)); ar.register_type(static_cast (NULL)); boost::serialization::void_cast_register
(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).