Boost logo

Boost Users :

Subject: Re: [Boost-users] Problem using serialization::xml_archive withpolymrphic classes
From: Robert Ramey (ramey_at_[hidden])
Date: 2010-09-02 20:17:51


przemyslaw.sliwa_at_[hidden] wrote:
> Hello,
>
> thanks for help with this. This has fixed the problem. However, I
> have got a much more complicated example which fails.
> I have a simple inheritance structure with 4 classes, they derive
> a->b->c->d nothing complex. say a is the mose base and d is the most
> derived class, Each class has got a virtual destructor. I can easily
> serialize object of type d but I cannot do this with a pointer to a
> this class. Basicaly invoking in the code
>
> std::vector<b*> tmpCcys;
> ar & boost::serialization::make_nvp("currencyEvents",
> tmpCcys);
>
> does not work at all! I can get to the point
>
> // retrieve the true type of the object pointed to
> // if this assertion fails its an error in this library
> assert(NULL != this_type);
>
> const boost::serialization::extended_type_info *
> true_type =
> i.get_derived_extended_type_info(t);
>
> // note:if this exception is thrown, be sure that derived
> pointer
> // is either registered or exported.
> if(NULL == true_type){
> boost::serialization::throw_exception(
> archive_exception(
> archive_exception::unregistered_class,
> true_type->get_debug_info()
> )
> );
> }
>
> in the oserializer.hpp where each element of the vector is dumped to
> the archive but call to i.get_derived_extended_type_info(t) throws an
> exception of an unknown type. It is not archive or event
> std::exception onlt catch(...) {...} can handle it and therefore it
> is not possible to see what is going on. The data under t looks fine
> but
>
> const extended_type_info *
> get_derived_extended_type_info(const T & t) const {
> // note: this implementation - based on usage of typeid (rtti)
> // only does something if the class has at least one virtual
> function.
> BOOST_STATIC_WARNING(boost::is_polymorphic<T>::value);
> return
>
> typeid_system::extended_type_info_typeid_0::get_extended_type_info(
> typeid(t)
> );
> }
>
>
> simply throws something which is not possible to handle correctly. I
> cannot step into typeid(t) on windows and VC++2005. As mentioned i
> have no problems at all with serializing object. Serializing pointers
> deos not work att all! I am exporting the class using
>
> BOOST_CLASS_EXPORT_GUID(d, "CurrencyEvent")

This look OK

> I have to mention that the most base class is a template and I export
> it as well using
>
> BOOST_CLASS_EXPORT_GUID(a<Currency>, "EventCurrency")
> BOOST_CLASS_EXPORT_GUID(a<CurrencyCouple>, "EventCurrencyCouple")
>
> similar
>
> BOOST_CLASS_EXPORT_GUID(b, "BaseCurrencyEvent")
> BOOST_CLASS_EXPORT_GUID(c, "RealCurrencyEvent")

The above should ont be necessary since only the "true" types need be exported.

> the classes a,b,c and d are within a namespace Events and
> defined/declared within a dll but this should not be a problem at all
> since I can serialize objects of the most derived class.

a) This would well be a problem. It turns out that serializing types whose
definitions are spread across multiple execution modules requires some
extra care to avoid violations of One Definition Rule and other problems.

b) Your code above looks correct to me

c) The fact that the thrown exception is one of the archive types suggests
that it's not an issue with the serialization library itself but rather the
DLL issue mentioned above.

I recommend:

a) make a small test program to test your serialization code in one module
and verify that it works. This sounds like a pain, but if you look at the test
programs in the package, you can see that it's not really a lot of work. And
it's a good investment in the future as you can leave the test programs as
part of your project and re-run them every time you enhance your code.
Saves a lot of future pain.

b) If a) above works, then make another test which does it in a DLL. If
my guess is correct, this will reproduce the problems above. Look
at the demo's with DLLs in the examples (and tests). You'll find
that in order to make these work well, eliminate duplicated code
and avoid violations of the ODR, that there is a clearer separation
between declaration (header files) and implemenation (*.cpp) files.
This usually means eliminating "inline" code to avoid haveing the
same code in different modules.

Robert Ramey

I would recommend:

a)



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