Boost logo

Boost Users :

Subject: Re: [Boost-users] [serialization] can I serialize concrete types that are not acessible where the archive is created
From: Massaro Alessio (Alessio.Massaro_at_[hidden])
Date: 2010-09-29 13:05:52


Thanks for the pointer Robert

I trawled up the following 2 items of doc, but made little process
http://www.boost.org/doc/libs/1_44_0/libs/serialization/doc/special.html#dlls
http://www.boost.org/doc/libs/1_44_0/libs/serialization/doc/special.html#plugins

If I follow the documentation I get a "derived class not registered..." at
runtime. So I looked at the unit tests.

The one for my case seems to be test_dll_plugin.cpp.

In that test polymorphic_base (the interface type known statically at the poiont
of serialization) uses the extended_type_info_no_rtti ETI scheme.

This is in contrast to polymorphic_derived2 (the concrete type UNknown statically at
the poiont of serialization) using the extended_type_info_typeid ETI scheme.

Do I *have to* use no_rtti for my abstract interface types?

If I use the typeid scheme everything builds but I get "derived class not registered..."
at runtime.

If I follow the test_dll_plugin.cpp pattern, then the code STATIC_ASSERTS
extended_type_info_no_rtti.hpp(87) at the point of serialization.

The STATIC_ASSERT comment says
            // if your program traps here - you failed to
            // export a guid for this type. the no_rtti
            // system requires export for types serialized
            // as pointers.

Adding
BOOST_CLASS_EXPORT_KEY(boost::shared_ptr<I_DoSomething>)
or
BOOST_CLASS_EXPORT_GUID(boost::shared_ptr<I_DoSomething>, "xyz")
to serialize.cpp will make no difference.

I really can't figure out what's wrong. I hope someone out there can spot
the problem!

##################### DLL/MODULE 1 #####################################

-------------------------------------------- interface.hpp

#include <boost/shared_ptr.hpp>

struct DLL_EXPORT I_DoSomething
{
        virtual const char * get_key() const = 0;
        virtual void doIt() = 0;
        static boost::shared_ptr<I_DoSomething> create(); // static factory

private:
        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & /* ar */, const unsigned int /* file_version */);
}

#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/extended_type_info_no_rtti.hpp>

BOOST_SERIALIZATION_ASSUME_ABSTRACT(I_DoSomething)
BOOST_CLASS_EXPORT_KEY(I_DoSomething)
BOOST_CLASS_TYPE_INFO(I_DoSomething, boost::serialization::extended_type_info_no_rtti<I_DoSomething>)

-------------------------------------------- ConcreteType.cpp

#include "interface.hpp"

class ConcreteType : public I_DoSomething
{
        virtual const char * get_key() const
        {
                return "ConcreteType";
        }
        ...
        .....
private:
        void serialize(Archive & ar, const unsigned int /*version*/)
        {
                ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(I_DoSomething);
                ar & ...
        }
}

boost::shared_ptr<I_DoSomething> I_DoSomething::create()
{
        return new ConcreteType();
}

#include <boost/serialization/export.hpp>
#include <boost/serialization/extended_type_info_typeid.hpp>

BOOST_CLASS_EXPORT_KEY(ConcreteType)
BOOST_CLASS_TYPE_INFO(ConcreteType, boost::serialization::extended_type_info_typeid<ConcreteType>)
BOOST_CLASS_EXPORT_IMPLEMENT(ConcreteType)

#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>

template DLLEXPORT void ConcreteType::serialize(boost::archive::xml_oarchive & ar, const unsigned int version);
template DLLEXPORT void ConcreteType::serialize(boost::archive::xml_iarchive & ar, const unsigned int version);

#include <boost/serialization/factory.hpp>
BOOST_SERIALIZATION_FACTORY_0(ConcreteType)

##################### DLL 2 which linked with DLL 1 #####################

-------------------------------------------- serialize.cpp

#include "interface.hpp"
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>

BOOST_CLASS_EXPORT_KEY(boost::shared_ptr<I_DoSomething>)

...
boost::shared_ptr<I_DoSomething> obj = I_DoSomething::create();
boost::text_oarchive oa;
oa << obj; // <-------- STATIC_ASSERTS at extended_type_info_no_rtti.hpp(87)
...


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