Guide to using serialization macro BOOST_CLASS_EXPORT
I am having some trouble understanding just where I am supposed to put BOOST_CLASS_EXPORT macros for classes I write --- in class headers (.h), in class implementation files (.cc), in applications that plan to save/load through base pointers? I have base class B, from which I derive lots of classes. I tried putting the BOOST_CLASS_EXPORT in the header files of each class, but soon found that this resulted in link-time errors due to multiple definitions. So, I moved the macro to an implementation (.cc) file, creating it if necessary, with the form: #include "Derived.h" BOOST_CLASS_EXPORT(Derived); The problem with this is that I have an application that does this: #include "Base.h" #include "Derived.h" // fails with or without this void foo() { Base* b = load("file.xml"); } Now, since no instance of Derived is appearing in my application, the linker apparently does not pull in the (expanded) macro, and when I run the application, I get an unregistered class exception. So, I removed all of the macros from the implementation files and put them in a header (again), that is designed for applications that may want to serialize (any) of my derived classes: #include "Base.h" #include "Derived.h" #include "BoostExports.h" void foo() { Base* b = load("file.xml"); } and this works fine. So my question is this: is this what other people do, or are there other solutions that people prefer? The problem with the above is that if I have 20 derived classes and put all the macro exports in BoostExports.h, even if my application may only be interested in a smaller subset, I have to pull in 20 header files each time, and I had hoped to avoid that. This is not a terrible thing, I just wondered what other approaches there might be. Bill
Bill Lear wrote:
I am having some trouble understanding just where I am supposed to put BOOST_CLASS_EXPORT macros for classes I write --- in class headers (.h), in class implementation files (.cc), in applications that plan to save/load through base pointers?
The whole concept behind BOOST_CLASS_EXPORT has been problematic for me for
a couple of reasons. As a result, the confusion you cite is a real one.
My intention was that:
a) BOOST_CLASS_EXPORT be part of the header file for a particular class.
b) A typical program would look like:
#include
I have base class B, from which I derive lots of classes. I tried putting the BOOST_CLASS_EXPORT in the header files of each class, but soon found that this resulted in link-time errors due to multiple definitions.
I'll look into this. It might be fixable. It was my intention to permit this. Note that including BOOST_CLASS_EXPORT to programs which don't in fact serialize through a base class pointer may instanciate code that is in fact never called. I'll look into this as well. Robert Ramey
On Friday, January 7, 2005 at 10:58:13 (-0800) Robert Ramey writes:
... The whole concept behind BOOST_CLASS_EXPORT has been problematic for me for a couple of reasons. As a result, the confusion you cite is a real one.
I settled on the following that a friend suggested, which seems to
work.
In my serialization/util.h file, I have the following:
template <class T>
void save(const T* t, const std::string& filename) { ... }
template <class T>
T* load(const std::string& filename) { ... }
at the bottom of this file, I have the following:
namespace dummy { struct bogus { static int bogus_method(); }; }
// force linking with util.cc
static int bogus_variable = dummy::bogus::bogus_method();
in serialization/util.cc, I have:
#include
I see how this would work. I would hope my method in the previous post would work as well. Robert Ramey Bill Lear wrote:
On Friday, January 7, 2005 at 10:58:13 (-0800) Robert Ramey writes:
... The whole concept behind BOOST_CLASS_EXPORT has been problematic for me for a couple of reasons. As a result, the confusion you cite is a real one.
I settled on the following that a friend suggested, which seems to work.
In my serialization/util.h file, I have the following:
template <class T> void save(const T* t, const std::string& filename) { ... }
template <class T> T* load(const std::string& filename) { ... }
at the bottom of this file, I have the following:
namespace dummy { struct bogus { static int bogus_method(); }; }
// force linking with util.cc static int bogus_variable = dummy::bogus::bogus_method();
in serialization/util.cc, I have:
#include
// expensive include which we wish to relegate to one one source file. #include
// the trigger method that forces others to link with this module int dummy::bogus::bogus_method() { return 0;}
The AllDerived.h file has includes for all my headers and all the BOOST_CLASS_EXPORT macros.
In my application code, I do this:
#include
#include and it all works flawlessly. I am spared from including the headers for my derived classes, and the accompanying export macros. The save and load routines work as expected.
Bill
participants (3)
-
Bill Lear
-
Jim Lear
-
Robert Ramey