[boost::serialization] Howto store derived classes through pointer to base - with templates and own archive?
Hi I have the following problem: My class structure is somehow like that: class A; // is pure virtual template <int NUM, typename ENUM> class B: public A; [...] I use my BinaryWrite archive class, as specified in thread: "[boost::serialization] Binary Stream with noAdditional Info: Here's the solution! [Howto derieve ownserialization archive?]" Now, when I try to stream a std::vector < boost::shared_ptr < A > > then I see in the function-trace log, that my writer has been called for the parent type A, but not for the derived types (B, C, ...). After this, I read again the "Except for one special case" part in the Archive Class Reference manual. After this, I added the following code in front of my archive type: ==================================================================== namespace image { class BinaryWriter; class BinaryReader; } #define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES ::image::BinaryWriter #define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES ::image::BinaryReader #include <boost/archive/detail/iserializer.hpp> #include <boost/archive/detail/oserializer.hpp> #include <boost/archive/detail/common_iarchive.hpp> #include <boost/archive/detail/common_oarchive.hpp> #include <boost/serialization/export.hpp> ==================================================================== But it still does not step into the correct child. After some more reading, I guess, that I'd have to use BOOST_CLASS_EXPORT(B), but that does not compile, because B is a template class. What's wrong, what's missing, what do I have to do? Thank you Regards Marc
Marc Wäckerlin wrote:
But it still does not step into the correct child. After some more reading, I guess, that I'd have to use BOOST_CLASS_EXPORT(B), but that does not compile, because B is a template class.
A, B, ... are in a namespace, let's say "abc". Now, I can write: BOOST_CLASS_EXPORT(::abc::B) But this must be outside of all namespaces. Then I get: -------------------------------------------------------------------------------- /usr/include/boost/archive/detail/iserializer.hpp:197: undefined reference to `boost::archive::detail::archive_pointer_iserializer<image::BinaryReader>::~archive_pointer_iserializer()' bitsets-bitsets.o: In function `~pointer_oserializer': /usr/include/boost/archive/detail/oserializer.hpp:184: undefined reference to `boost::archive::detail::archive_pointer_oserializer<image::BinaryWriter>::~archive_pointer_oserializer()' -------------------------------------------------------------------------------- What's wrong, what's missing, what do I have to do? BTW: This newsgroup is *extremely* slow. I wait for hours and hours until I see my message! Regards Marc
Not sure whether this helps, but just from reading what BOOST_CLASS_EXPORT does I think you can not export incomplete types. If B is template, then a unique name is generated by a compiler for every specialization of B. Let's say: template<class T> struct B { ... }; B<int> is different type from B<double>. BOOST_CLASS_EXPORT will not generate export of B<all_possible_types>. You need to explicitly state which B<of_type_X> you would like to export. This is my asumption. Good Luck, Ovanes On Mon, January 29, 2007 16:36, Marc Wäckerlin wrote:
Marc Wäckerlin wrote:
But it still does not step into the correct child. After some more reading, I guess, that I'd have to use BOOST_CLASS_EXPORT(B), but that does not compile, because B is a template class.
A, B, ... are in a namespace, let's say "abc". Now, I can write: BOOST_CLASS_EXPORT(::abc::B) But this must be outside of all namespaces.
Then I get: -------------------------------------------------------------------------------- /usr/include/boost/archive/detail/iserializer.hpp:197: undefined reference to `boost::archive::detail::archive_pointer_iserializer<image::BinaryReader>::~archive_pointer_iserializer()' bitsets-bitsets.o: In function `~pointer_oserializer': /usr/include/boost/archive/detail/oserializer.hpp:184: undefined reference to `boost::archive::detail::archive_pointer_oserializer<image::BinaryWriter>::~archive_pointer_oserializer()' --------------------------------------------------------------------------------
What's wrong, what's missing, what do I have to do?
BTW: This newsgroup is *extremely* slow. I wait for hours and hours until I see my message!
Regards Marc
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
BOOST_EXPORT must a) be invoked outside of any namespace b) not have characters like < >, :: etc in it c) refer to a complete type If these restrictions create difficulty, look up the definition of the macro in export.hpp as well as information on export in the documentation and invoke another macro or the template directly. Robert Ramey
Robert Ramey wrote:
BOOST_EXPORT must a) be invoked outside of any namespace b) not have characters like < >, :: etc in it c) refer to a complete type
Then, how to export a type that is: 1) a template class and/or 2) inside a namespace and/or 3) non-complete? Thank you Regards Marc
Robert Ramey wrote:
BOOST_EXPORT must a) be invoked outside of any namespace b) not have characters like < >, :: etc in it c) refer to a complete type
That's not even the problem. I extended my example from the last thread by a simple class A - no template, no namespace - and it reproduces the problem. Please have a look at the attachment. Other question: My main problem is, that derived classes are not stored through (smart-) pointer to base. Will this problem be resolved when I'll be able to export, or what's the problem there and what's "BOOST_CLASS_EXPORT" for? Is it only for assigning a name? Then, do I really need it (because my serialiser does neither care about, nor stores meta information)? Thank you Regards Marc
Marc Wäckerlin wrote:
Robert Ramey wrote:
BOOST_EXPORT must a) be invoked outside of any namespace b) not have characters like < >, :: etc in it c) refer to a complete type
That's not even the problem. I extended my example from the last thread by a simple class A - no template, no namespace - and it reproduces the problem.
Please have a look at the attachment.
Other question: My main problem is, that derived classes are not stored through (smart-) pointer to base.
Then BOOST_CLASS_EXPORT should not be necessary. It is only used to assign an external name to a type.
Will this problem be resolved when I'll be able to export, or what's the problem there and what's "BOOST_CLASS_EXPORT" for? Is it only for assigning a name? Then, do I really need it (because my serialiser does neither care about, nor stores meta information)?
I do not see how a serializer which does not store meta information can work. I suggest separating issues relating to serialization of classes from those related to creation of custom archives. a) test serialization of your classes one of the archives delivered with the system b) test your custom archive with some of the class serializations delivered with the system. It looks like your example fails to link. Note that the archives included with the system used explicit instantiation to generated templated code not otherwise explicitly referred to. Robert Ramey
"Robert Ramey" <ramey@rrsd.com> writes:
BOOST_CLASS_EXPORT should not be necessary. It is only used to assign an external name to a type.
That does not correspond to my understanding. -- Dave Abrahams Boost Consulting www.boost-consulting.com
OK. Let me re-phrase this. I believe that the only time BOOST_CLASS_EXPORT (or something like it) should be necessary is when one serializes a derived class through an abstract pointer. It has two functions. First, it ensures that code which would not be otherwise instantiated is in fact instantiated. Second, it relates an externalizable text string to the type being serialized. Robert Ramey David Abrahams wrote:
"Robert Ramey" <ramey@rrsd.com> writes:
BOOST_CLASS_EXPORT should not be necessary. It is only used to assign an external name to a type.
That does not correspond to my understanding.
Robert Ramey wrote:
I believe that the only time BOOST_CLASS_EXPORT (or something like it) should be necessary is when one serializes a derived class through an abstract pointer. It has two functions. First, it ensures that code which would not be otherwise instantiated is in fact instantiated. Second, it relates an externalizable text string to the type being serialized.
So I probably need to call it for the first reason (not for the second one). Any Idea why there's a link problem? BTW: The idea in my concept is, that you can only deserialize the correct object, which contains preinitialized instances, so that these instances know, what type they are, and how to deserialize. I'll probably post an example, when it all works.
Marc Wäckerlin wrote:
Any Idea why there's a link problem?
I received no answer until now, so I'd like to ask a bit differently: Are you able to reproduce the link-problem? Or have you any idea, why it occurs? According to the code, the missing method is inline - so why doesn't it link? It should be reproducible with the example I sent you, an the GNU-gcc. Thank you Regards Marc
Marc Wäckerlin wrote:
Marc Wäckerlin wrote:
Any Idea why there's a link problem?
I received no answer until now, so I'd like to ask a bit differently:
Are you able to reproduce the link-problem?
It should be reproducible with the example I sent you, an the GNU-gcc.
The example is too complex to help me. It mixes serialization and a new archive so its hard to see what might be happening.
Or have you any idea, why it occurs? According to the code, the missing method is inline - so why doesn't it link?
I suspect that certain code has has to be instaticiated explictly. See the archives included with the serialization library for examples.
Thank you Regards Marc
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (4)
-
David Abrahams
-
Marc Wäckerlin
-
Ovanes Markarian
-
Robert Ramey