[serialization] can I serialize concrete types that are not acessible where the archive is created

Hi there! Does boost::serialization work with interfaces and static factory methods? (shown below) Note how the Concrete type is not actually known at the point where the archive is instantiated, and the two are actually in two different modules. In fact, I have indeed tried the following line in ConcreteType.cpp but the registration is not seen by the text_oarchive in DLL 2 BOOST_CLASS_EXPORT_GUID(ConcreteType, "ConcreteType") Perhaps using a singleton archive on which I register every type (from Multiple DLLs) and that I use to serialize every object? But how would I provide access to register_type on such a singleton? And how would I use it on different stream instances? (a clone?) I m trawling through the boost::serialization code, and cannot find a way to make it work. Thanks in advance for any pointers/help! ##################### DLL/MODULE 1 ##################################### ### interface.hpp struct DLL_EXPORT I_DoSomething { void doIt() = 0; static I_DoSomething* create(); // static factory } ### ConcreteType.cpp #include "interface.hpp" class ConcreteType : public I_DoSomething { ... } I_DoSomething* create() { return new ConcreteType(); } ##################### DLL 2 which linked with DLL 1 ##################### ### serialize.cpp #include "interface.hpp" #include <boost/archive/text_oarchive.hpp> ... I_DoSomething* obj = I_DoSomething::create(); boost::text_oarchive oa; oa << obj; ...

Massaro Alessio wrote:
Hi there!
Does boost::serialization work with interfaces and static factory methods? (shown below)
Note how the Concrete type is not actually known at the point where the archive is instantiated, and the two are actually in two different modules. In fact, I have indeed tried the following line in ConcreteType.cpp but the registration is not seen by the text_oarchive in DLL 2
BOOST_CLASS_EXPORT_GUID(ConcreteType, "ConcreteType")
The above is basically on the right track. Trawl the documentation for the explanation of special considerations related to DLLS and particularly with regards to EXPORT. Robert Ramey

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#dll... http://www.boost.org/doc/libs/1_44_0/libs/serialization/doc/special.html#plu... 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) ...
participants (2)
-
Massaro Alessio
-
Robert Ramey