Boost logo

Boost :

From: Robert Ramey (ramey_at_[hidden])
Date: 2005-08-10 10:13:47


SourceForge.net wrote:

> I made some progress after reading "rationale" though
> some things still give headaches.

Could you expand on this? I am curious as to how this works for users.

> I have polymorphic class hierarchy which gets
> serialized thru base ptrs (along with shared_ptr stuff).
> When using portable_binary_oarchive/iarchive (taken
> from boost example) an assert() triggers which raises
> some questions.
>
> oserializer.hpp:
>
> -------------- snip --------------
>
> // sice true_type is valid, and this only gets made if
> the
> // pointer oserializer object has been created, this
> should never fail
> bpos_ptr =
> archive_pointer_oserializer<Archive>::find(* true_type);
> assert(NULL != bpos_ptr);
> if(NULL == bpos_ptr)
> boost::throw_exception(
>
> archive_exception(archive_exception::unregistered_class)
> );
>
> -------------- snip --------------

When compiled with debug mode - this traps an assert. When compiled for
release, it throws exception "unregistered class". You should be trapping
the archive exceptions.

The basic problem is that derived classes have to be "registered" or
"exported" in order for the serialization system to know about them. Look in
the documentation for the exceptions where you will find an explanation of
this error and how to address it.

>
> The classes usually contain:
>
> "template<class Archive>
> void serialize( Archive & ar, const unsigned int /*
> version */)"
>
> stuff, along with explicit:
>
> "boost::serialization::void_cast_register<Derived,
> Base>(0,0);"
>
> in ctors (or it doesnt work).
>
> "this_type" = abstract base
> "true_type" = derived
>

it should be necessary to explicitly call void_cast_register only in unusual
cases. The common case is for the derived class to inlcude ar <<
base_object<base_class>(*this) which invokes void_cast_register. The only
time I've had to call void_cast_register explicitly is when I don't want to
have a serialization function in the base class itself. But this has been a
rare case. So

a) first try using base_object. If the base class doesn't have any data,
include an empty serialize function.
b) once the above works, if the base class doesn't have any data, replace
base_object with void_cast_register<Base, Derived>

> BTW ... could you make "portable_binary_oarchive" (and
> iarchive) included in available boost archive types?
> I find it useful because serialization is used in cross
> platform protocol stacks (little vs. big endian archs).

this started out as an example of how to derived from a pre-existing archive
type. Its not really ready for prime time as
a) it doesn't support a portable format for floats and doubles
b) it depends upon endian.hpp which doesn't seem to be correctly implemented
for all compilers / machines that boost works with.
c) If I make this "official", I would have to make another example.

> Is there any chance to reduce binary overhead due to
> registration data (shared_ptr/type info ... binary size
> almost doubled due to contained type info in small
> payloads).

> Can stringified type info be omitted/shortened (i use
> hierachial namespaces which blow the length)?

I believe you could address these issues by using the "registration" method
rather then "export" to commuincate derived classes to the serialization
library. These place only a small digit into the library.

Robert Ramey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk