Куда поместить BOOST_CLASS_EXPORT для повышения:: сериализация?

Я пытаюсь сериализировать указатель на полиморфный класс Shape. Таким образом, я должен использовать BOOST_CLASS_EXPORT макрос для определения GUID для каждого подкласса. Проблема: куда поместить его?

Позвольте мне показать минимальный тестовый сценарий сначала:

shapes.hpp

#include 
#include 
#include 

class Shape {
    friend class boost::serialization::access;

    template
    void serialize(Archive &ar, unsigned int const version) {
        // nothing to do
    }

    public:
        virtual ~Shape() { }
};

class Rect : public Shape {
    friend class boost::serialization::access;

    template
    void serialize(Archive &ar, unsigned int const version) {
        ar & boost::serialization::base_object(*this);
    }

    public:
        virtual ~Rect() { }
};

#ifdef EXPORT_IN_HEADER
    BOOST_CLASS_EXPORT(Rect)
#endif

export.cpp

#include 
#include "shapes.hpp"

#ifdef EXPORT_IN_OBJECT
    BOOST_CLASS_EXPORT(Rect)
#endif

main.cpp

#include 
#include 
#include 
#include "shapes.hpp"

#ifdef EXPORT_IN_MAIN
    BOOST_CLASS_EXPORT(Rect)
#endif

int main() {
    Shape *shape = new Rect();
    boost::archive::text_oarchive ar(std::cout);
    ar << shape;
}

На gcc я компилирую их с

g++ -omain main.cpp export.cpp -Wl,-Bstatic -lboost_serialization-mt -Wl,-Bdynamic -DEXPORT_IN_XXX

Здесь, export.cpp может выглядеть немного глупым. В моей фактической ситуации это содержит класс включения, который использует идиому PIMPL и пытается сериализировать ее (полиморфный) Shape реализация. Важный момент: BOOST_CLASS_EXPORT мог быть в другом объектном файле, чем код, который вызывает сериализацию.

Таким образом, вот проблема: где использовать BOOST_CLASS_EXPORT? У меня есть три опции, которые могут быть включены с помощью EXPORT_IN_XXX макросы.

  1. EXPORT_IN_MAIN работы, но не то, что я хочу. Код, вызывающий сериализацию не должен должен быть знать о деталях реализации класса PIMPL.

  2. EXPORT_IN_OBJECT компиляции, но не работает: это приводит к a boost::archive::archive_exception с сообщением unregistered void cast. Согласно документации, это должно быть решено путем сериализации использования базовых классов boost::serialization::base_object, как я сделал, но это не помогает.

  3. EXPORT_IN_HEADER даже не компилирует. Макрос BOOST_CLASS_EXPORT расширяется до шаблонной специализации (который мы хотели бы быть в заголовочном файле), но также и к definitiof статического участника там. Таким образом, я получаю ошибку компоновщика о a multiple definition of 'boost::archive::detail::init_guid::guid_initializer'.

Если это имеет значение, я использую g ++ 4.4.3 и Повышение 1.40.

12
задан Thomas 3 August 2010 в 12:16
поделиться