Boost logo

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