|
Boost Users : |
From: Robert Ramey (ramey_at_[hidden])
Date: 2006-02-28 11:00:11
RIVASSEAU Jean Noel wrote:
> Hello,
>
> CommonSerialize.h - remove the following
>
> #include <boost/archive/xml_oarchive.hpp>
> #include <boost/archive/xml_iarchive.hpp>
>
> and add the following:
>
> #include <boost/serialization/export.hpp>
>
> test_independent.cc - change the top to look like the following:
>
> // INDEPENDENT TEST
>
> #include <boost/archive/xml_oarchive.hpp>
> #include <boost/archive/xml_iarchive.hpp>
>
> #include <MObject.h>
> #include <MObject_serialization.hh>
> #include <MemberVariableSpecification.h>
> #include <MemberVariableSpecification_serialization.hh>
> #include <fstream>
> This won't work. Since you now have the archive headers in only one
> place, there is no multiple definition problem. However serialization
> code is *not* instantiated for MObject or
> MemberVariableSpecification. This is normal since when compiling the
> .cc that contains this code, there is no archive header included and
> so the export.hpp has no effect. The code is here but is not
> instantiated.
>
> So in order to follow this advice:
>
> a) include all boost/serialization/.. headers in each class file.
> b) include NO boost/archive/... headers in any class file
> c) make a "template instantiation module" which instanticiates code
> for all archives I plan to use. This can be either in the app or in
> a library.
> d) lihk and execute without problem.
>
> I have to explicitly instantiate the serialization code for the
> needed archive in the .cc files. That is, do:
>
> template void save<boost::archive::xml_oarchive>(
> boost::archive::text_oarchive & ar, const MObject & m,
> const unsigned int file_version
> );
>
> And same for load. This is what you do in demo_pimpl.cpp. Is that
> what you usually do and recommend to do?
In a smaller program - example the tests. One can include the serialization
headers which might contain BOOST_EXPORT after any archives used.
This will guarentee that needed code is instantiated.
In larger programs, I use the method illustrated in demo_pimpl to
explicitly instantiate code for archives that are used.
On a larger project, I would make an instantiation module which
will instantiate code for all the archives I might ever use. Alternatively,
I might use the polymorphic archive. In this last case I do the following
to avoid "code bloat".
a) I build a separate library of class modules.
b) I instantiate all code that might be used
c) I use compile time switches to make linking occur at the function
level rather than the module level.
d) I link my "real project" against this class library.
> This has the advantage to avoid big compilations (these code
> instantiations will only occur when the class to serialize has indeed
> changed).
Indeed - and this is a big advantage for xml_archives which take quite
a bit of time to compile.
> However this has the inconvenience of manually instantiating every
> template (and if you want to change your archive format , eg from
> text to xml for example, everything needs to be changed).
This is true. But this is a minor in my opinion. The root cause of this
situation is that linkers complain about multiply defined functions
- even when those functions are identical. Maybe someday we'll
have smarter linkers - but until then this works quite well. It does
require that one spend a little time explicitly considering code
instantiation. But this isn't necessarily bad. Letting the compile/linker
do all the work will lead to code bloat and compilation time problems.
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