|
Boost Users : |
From: Hubert Hoover (hugh_at_[hidden])
Date: 2006-07-09 23:35:26
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).
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net