Я пытаюсь сериализировать указатель на полиморфный класс 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
макросы.
EXPORT_IN_MAIN
работы, но не то, что я хочу. Код, вызывающий сериализацию не должен должен быть знать о деталях реализации класса PIMPL.
EXPORT_IN_OBJECT
компиляции, но не работает: это приводит к a boost::archive::archive_exception
с сообщением unregistered void cast
. Согласно документации, это должно быть решено путем сериализации использования базовых классов boost::serialization::base_object
, как я сделал, но это не помогает.
EXPORT_IN_HEADER
даже не компилирует. Макрос BOOST_CLASS_EXPORT
расширяется до шаблонной специализации (который мы хотели бы быть в заголовочном файле), но также и к definitiof статического участника там. Таким образом, я получаю ошибку компоновщика о a multiple definition of 'boost::archive::detail::init_guid
.
Если это имеет значение, я использую g ++ 4.4.3 и Повышение 1.40.