Estoy tratando de serializar un puntero a una clase polimórfica Shape
. Entonces necesito usar el BOOST_CLASS_EXPORT
macro para definir un GUID para cada subclase. El problema: ¿dónde ponerlo?¿Dónde poner BOOST_CLASS_EXPORT para impulsar :: serialización?
Te voy a enseñar un caso de prueba mínima en primer lugar:
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;
}
En gcc, puedo compilar estos con
g++ -omain main.cpp export.cpp -Wl,-Bstatic -lboost_serialization-mt -Wl,-Bdynamic -DEXPORT_IN_XXX
Aquí, export.cpp
puede parecer un poco tonto. En mi situación actual, contiene una clase adjunta que usa el modismo PIMPL, y trata de serializar su implementación (polimórfica) Shape
. El punto importante es: el BOOST_CLASS_EXPORT
podría estar en un diferente archivo de objeto que el código que invoca la serialización.
Así que aquí está el problema: dónde usar BOOST_CLASS_EXPORT
? Tengo tres opciones, que se pueden habilitar usando las macros EXPORT_IN_XXX
.
EXPORT_IN_MAIN
funciona, pero no es lo que quiero. El código que invoca la serialización no debería necesitar conocer los detalles de implementación de la clase PIMPL.EXPORT_IN_OBJECT
compila, pero no funciona: el resultado es unaboost::archive::archive_exception
con el mensajeunregistered void cast
. De acuerdo con documentation, esto debería resolverse serializando clases base usandoboost::serialization::base_object
, como lo hice, pero no ayuda.EXPORT_IN_HEADER
ni siquiera se compila. El macroBOOST_CLASS_EXPORT
se expande a una especialización de plantilla (que nos gustaría que estuviese en el archivo de encabezado), pero también a la definición de un miembro estático en el mismo. Entonces recibo un error del enlazador sobremultiple definition of 'boost::archive::detail::init_guid<Rect>::guid_initializer'
.
Si es importante, estoy usando g ++ 4.4.3 y Boost 1.40.
¿Ha resuelto este problema? He encontrado este problema yo mismo, obteniendo una excepción de clase no registrada en tiempo de ejecución o errores 'boost :: archive :: detail :: init_guid :: guid_initializer' en tiempo de compilación. Estoy bastante perplejo, así que si lo has entendido desde que hice esta pregunta, ¡realmente apreciaría que compartieras! ¡Gracias! –
bguiz
@bguiz: Realmente no lo resolvió, no. Ver mi respuesta a continuación. – Thomas