Boost logo

Boost Users :

Subject: [Boost-users] [Serialization] Linker error on BOOST_CLASS_EXPORT upgrading from 1.44.0
From: Enrico Carrara (enrico.ecamail_at_[hidden])
Date: 2011-07-25 04:50:15


Hello,

I am facing a problem with serialization as implemented in Boost 1.47.0
which I did not experience in version 1.44.0.

The problem appears as a series of linker errors (Visual C++ 8.0 (VS2005),
WinXP 32bit):

1>Compiling...
1>Model_SerializationXml.cpp
1>Model_SerializationTxt.cpp
1>Compiling manifest to resources...
1>Linking...
1>Model_SerializationXml.obj : error LNK2005: "public: static struct
boost::archive::detail::extra_detail::guid_initializer<class
sm::CompLoad_Test> const & const
boost::archive::detail::extra_detail::init_guid<class sm::CompLoad_Test>::g"
(?g@?$init_guid_at_VCompLoad_Test_at_sm@@@extra_detail_at_detail@archive_at_boost
@@2ABU?$guid_initializer_at_VCompLoad_Test_at_sm@@@2345_at_B) already defined in
Model_SerializationTxt.obj
[...many more similar errors]

The scenario is as follows:
I have a considerable bunch of classes which must be serialized by means of
both text and XML archives.
To this purpose, I have two compilation units, "Model_SerializationTxt.cpp"
and "Model_SerializationXml.cpp", as follows:

/////////////////////////////////////////////////
// Model_SerializationTxt.cpp
[...]
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/archive_exception.hpp>
[...]
#include "SerClassExport.h"
[...]
/////////////////////////////////////////////////

/////////////////////////////////////////////////
// Model_SerializationXml.cpp
[...]
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/archive_exception.hpp>
[...]
#include "SerClassExport.h"
[...]
/////////////////////////////////////////////////

/////////////////////////////////////////////////
// SerClassExport.h
[...]
// APPLICATION_DEPENDENT: Include here files
// relevant to model classes to be exported
// for serialization
#include "Model_Root.h"
#include "SM/SM_Node.h"
[...Many more class definition headers]
[...]
#include <boost/serialization/export.hpp>
// APPLICATION_DEPENDENT: Include here files
// relevant to model classes to be exported
// for serialization
BOOST_CLASS_EXPORT(model::Root)
BOOST_CLASS_EXPORT(sm::Node)
[...Many more class export definitions]
[...]
/////////////////////////////////////////////////

The problem seems to be related to the fact that BOOST_CLASS_EXPORT is
defined twice in my project.
In Boost 1.44.0, struct guid_initializer was defined in "export.hpp" inside
an anonymous namespace, while in Boost 1.47.0 - actually, since version
1.45.0 - the definition is inside namespace extra_detail, even if the
comment above is unchanged:

/////////////////////////////////////////////////
// export.hpp in Boost 1.44.0
[...]
// Note INTENTIONAL usage of anonymous namespace in header.
// This was made this way so that export.hpp could be included
// in other headers. This is still under study.

namespace {

template<class T>
struct guid_initializer
[...]
#define BOOST_CLASS_EXPORT_IMPLEMENT(T)\
    namespace boost {\
    namespace archive {\
    namespace detail {\
    namespace {\
    template<>\
    struct init_guid< T > {\
        static guid_initializer< T > const & g;\
    };\
    guid_initializer< T > const & init_guid< T >::g =\
        ::boost::serialization::singleton<\
            guid_initializer< T >\
>::get_mutable_instance().export_guid();\
    }}}}\
[...]
/////////////////////////////////////////////////

/////////////////////////////////////////////////
// export.hpp in Boost 1.47.0
[...]
// Note INTENTIONAL usage of anonymous namespace in header.
// This was made this way so that export.hpp could be included
// in other headers. This is still under study.

namespace extra_detail {

template<class T>
struct guid_initializer
[...]
#define BOOST_CLASS_EXPORT_IMPLEMENT(T)\
    namespace boost {\
    namespace archive {\
    namespace detail {\
    namespace extra_detail {\
    template<>\
    struct init_guid< T > {\
        static guid_initializer< T > const & g;\
    };\
    guid_initializer< T > const & init_guid< T >::g =\
        ::boost::serialization::singleton<\
            guid_initializer< T >\
>::get_mutable_instance().export_guid();\
    }}}}\
[...]
/////////////////////////////////////////////////

I guess that this might have a role in originating the linker problem.

How can I avoid this error? I already tried including the list of
BOOST_CLASS_EXPORT only once, i.e in Model_SerializationTxt.cpp only. This
solved the linker problem, but serialization of data in XML was then
impossible (runtime error).
Unfortunately, merging the two compilation units in one is not possible,
because the compiler (Visual C++ 8.0) goes out of memory while compiling the
big unit (process memory grows beyond 2GB).
Is there, in your opinion, a solution or a workaround to this situation?

Let me apologize for the very long mail, I did not succeed in shortening it
further.

Looking forward to any possible advice,
thank you in advance for your attention.
Enrico



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