Я пытаюсь сериализовать указатель на полиморфный класс Shape
. Поэтому мне нужно использовать BOOST_CLASS_EXPORT
macro для определения GUID для каждого подкласса. Проблема: где это сказать?Где разместить BOOST_CLASS_EXPORT для boost :: serialization?
Позвольте мне показать минимальный тестовый пример первый:
shapes.hpp
#include <boost/serialization/access.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
class Shape {
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive &ar, unsigned int const version) {
// nothing to do
}
public:
virtual ~Shape() { }
};
class Rect : public Shape {
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive &ar, unsigned int const version) {
ar & boost::serialization::base_object<Shape>(*this);
}
public:
virtual ~Rect() { }
};
#ifdef EXPORT_IN_HEADER
BOOST_CLASS_EXPORT(Rect)
#endif
export.cpp
#include <boost/serialization/export.hpp>
#include "shapes.hpp"
#ifdef EXPORT_IN_OBJECT
BOOST_CLASS_EXPORT(Rect)
#endif
main.cpp
#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/export.hpp>
#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;
}
На НКУ, компилировать их с
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
компилируется, но не работает: в результате получается сообщениеboost::archive::archive_exception
с сообщениемunregistered void cast
. Согласно documentation, это должно быть разрешено путем сериализации базовых классов с использованиемboost::serialization::base_object
, как и я, но это не помогает.EXPORT_IN_HEADER
даже не компилируется. МакросBOOST_CLASS_EXPORT
расширяется до специализации шаблона (который мы хотели бы быть в файле заголовка), но также и для определения статического члена в нем. Поэтому я получаю ошибку компоновщика околоmultiple definition of 'boost::archive::detail::init_guid<Rect>::guid_initializer'
.
Если это имеет значение, я использую g ++ 4.4.3 и Boost 1.40.
Вы решили эту проблему? Я сам столкнулся с этой проблемой, либо получив незарегистрированное исключение класса во время выполнения, либо 'boost :: archive :: detail :: init_guid :: guid_initializer' ошибки во время компиляции. Я очень взволнован, поэтому, если вы поняли это, задав этот вопрос, я бы очень признателен, если бы вы поделились! Благодаря! –
bguiz
@bguiz: Не совсем решил, нет. См. Мой ответ ниже. – Thomas