|
Boost Users : |
Subject: Re: [Boost-users] serialization: "derived class not registered orexported" exception , 1.45 boost
From: Robert Ramey (ramey_at_[hidden])
Date: 2010-12-19 17:47:55
Hicham Mouline wrote:
> Hello,
>
> I have moved all serialization code in a separate static library that
> I called serialization. This, in my case, depends on mpi.
> The headers in this static library:
> 1. include <boost/serialization/export.hpp>
> 2. include the definition of the derived class being serialized
> 3. declare a template function serialize() that takes a
> reference to the derived class being serialized in the
> boost::serialization namespace
> 4. invoke the BOOST_CLASS_EXPORT_KEY(<derivedclass>) macro at
> the global namespace scope
>
> The corresponding source files in this static library:
> 1. include the header
> 2. define the function template serialize()
> 3. explicitly instantiate the serialize() function with all the
> archives used: mpi::packed_iarchive and mpi::packed_oarchive in the
> boost::serialization namespace
> 4. invoke the BOOST_CLASS_EXPORT_IMPLEMENT(<derivedclass>)
> macro at the global namespace scope
>
> The main program links against this static library, and invokes a mpi
> function (broadcast) that serializes by the base pointer. The base
> class is polymorphic. All class derivations are public.
>
> Debugging, the code reaches : archive/detail/oserializer.hpp
>
> boost::archive::detail::save_pointer_type<boost::mpi::packed_oarchive>::polymorphic::save<baseclass>(boost::mpi::packed_oarchive
> & ar={...}, baseclass& t={...}) Line 400 + 0x38 bytes
>
> where NULL==true_type
>
> However, looking at the t argument of save(), it shows that is the
> correct derived object. But the type T is the base class.
>
> What am I missing?
Not much, you're almost there.
You've invoked the EXPORT macros so the runtime static objects
are created in the library. So far, so good. But you're mainline doesn't
refer to them, so they are not included in your executable. I think the
easiest way to do this is to include in the execution build something like:
my_module.cpp
#include "my_type.hpp"
BOOST_SERIALIZATION_EXPORT_IMPL(my_type)
...
other types.
I know, this conflicts with the idea of putting everything in the library
which is what I would prefer, but I haven't found anyother way to do it.
Also note the difference between static and dynamic libraries. If you're
using a static library, you only add to your executable that which you
explicitly refer to - so some stuff we need doesn't get added. If you
make a DLL, everything is in the DLL so we don't have this problem -
though we likely have a bunch of stuff we might not be using.
There is another way also. You could create a module in your
library which contains something like:
myclass::init(){
}
BOOST_SERIALIZATION_EXPORT_IMPL(my_type)
and call myclass::init from your mainline executable. They might
or mightnot work depending on your linker switches and how
smart your linker is.
Robert Ramey
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