2012-02-08 25 views
6

Estoy buscando un ejemplo (de trabajo) para serializar externamente una estructura de clases en una DLL. Actualmente no puedo encontrar ningún ejemplo para eso. La documentación de Boost solo está indicando algunas macros, los foros y grupos de noticias solo están discutiendo problemas específicos con sus soluciones.Poner la serialización de una clase en una DLL

Así que estoy pidiendo un ejemplo para serializar (externamente) una estructura de clases como la siguiente. Junto con el código de clase, agregué un código mío para la serialización (que no funciona, ver el mensaje de error en la parte inferior).

class Foo 
{ 
public: 
    Foo() { number_ = 0; } 
    virtual ~Foo() {} 

    int getNumber() { return number_; } 
    void setNumber(int var) { number_ = var; } 
private: 
    int number_; 
}; 

class Bar : public Foo 
{ 
public: 
    Bar() { doubleNumber_ = 0.0; } 
    virtual ~Bar() {} 

    double getDouble() { return doubleNumber_; } 
    void setDouble(double var) { doubleNumber_ = var; } 

private: 
    double doubleNumber_; 
}; 

Todo lo que tengo hasta ahora es un código como éste:

serializeFoo.h

#ifndef _SERIALIZE_FOO_H_ 
#define _SERIALIZE_FOO_H_ 

#include "Foo.h" 
#include <boost/serialization/split_free.hpp> 
#include <boost/serialization/version.hpp> 

namespace boost { 
namespace serialization { 

template <typename Archive> 
void save(Archive& ar, const Foo& object, const unsigned int version) 
{ 
    ar << object.getNumber(); 
} 

template <typename Archive> 
void load(Archive& ar, Foo& object, const unsigned int version) 
{ 
    int number; 
    ar >> number; 
    object.setNumber(number); 
} 

}} //namespace brackets 

BOOST_SERIALIZATION_SPLIT_FREE(Foo) 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/export.hpp> 
BOOST_CLASS_EXPORT_KEY(Foo) 

#endif //_SERIALIZE_FOO_H_ 

serializeFoo.cpp

#include "serializeFoo.h" 
BOOST_CLASS_EXPORT_IMPLEMENT(Foo) 

seriali zeBar.h:

#ifndef _SERIALIZE_BAR_H_ 
#define _SERIALIZE_BAR_H_ 

#include "Bar.h" 
#include <boost/serialization/split_free.hpp> 
#include <boost/serialization/version.hpp> 

namespace boost { 
namespace serialization { 

template <typename Archive> 
void save(Archive& ar, const Bar& object, const unsigned int version) 
{ 
    ar << base_object<Foo>(object); 
    ar << object.getDouble(); 
} 

template <typename Archive> 
void load(Archive& ar, Bar& object, const unsigned int version) 
{ 
    double doubleNumber; 
    ar >> doubleNumber; 
    object.setDouble(doubleNumber); 
} 

}} //namespace brackets 

BOOST_SERIALIZATION_SPLIT_FREE(Bar) 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/export.hpp> 
BOOST_CLASS_EXPORT_KEY(Bar) 

#endif //_SERIALIZE_BAR_H_ 

serializeBar.cpp:

#include "serializeBar.h" 
BOOST_CLASS_EXPORT_IMPLEMENT(Bar) 

El código de serialización entra en un DLL y se debe utilizar en otro proyecto con clases de Foo y Bar. Todo compila bien, pero en tiempo de ejecución aparece el mensaje
unregistered class - derived class not registered or exported

también lo hizo que utiliza las macros equivocadas? ¿Extraño una macro? ¿Es correcto el código anterior o hay algún tipo de error estructural? Quizás esto podría ser útil para muchas otras personas, no creo que poner la serialización de una clase en una DLL sea muy exótico ...

+0

Lo que vi en Boost-docs fue 'BOOST_SERIALIZATION_FACTORY_0 (Foo)', pero no sé si es necesario y si debería usarlo. Enlace: http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/special.html#dlls – MOnsDaR

+0

Bueno, si te hace sentir mejor, tengo un proyecto en el que funciona bien , y el código se ve bastante idéntico a lo que tiene, excepto por el hecho de que incluyo los encabezados de archivo en la parte superior del archivo de encabezado. PD es técnicamente un '.so', no un' .dll', no debería marcar la diferencia ... – TC1

+0

Tienes razón, quise escribir "Shared lib" al principio, pero escribí DLL porque quería mostrar que actualmente es un problema con este tipo específico de lib compartido. – MOnsDaR

Respuesta

1

me encontré con un problema similar hace poco, 3 años después de que se hizo esta pregunta. Finalmente descubrí una solución para resolverlo. En el ejemplo de arriba.

  • Bar es una subclase de Foo, por lo que deben estar registrados/exportado;
  • serializeFoo.cpp crea una clase de plantilla GUID para registrar/exportar Foo;
  • serializeBar.cpp crea una clase de plantilla de GUID para registrar/exportar Bar;
  • Se respetan las reglas para incluir todos los tipos de archivos necesarios antes de exportar las claves de clase;
  • Ambas unidades de traducción están unidas para crear una DLL.

Asumo en su exe, mientras que usted está tratando de serializar un puntero Foo* apuntando a un objeto Bar, que tiene el error "no registrada blahblah clase". Esto es porque Boost.Serialization de alguna manera no genera correctamente un GUID para la clase Barantes de se llama a la función serializar.

No sé por qué sucede esto, pero parece que el GUID se genera de manera perezosa: si no se usa ninguno de los símbolos de la unidad de traducción serializeBar.cpp, ninguno del código de creación de instancias/inicialización definido en esa traducción se realizará la unidad, que incluye el registro/exportación de clase de Bar.

Para probar esto, se puede tratar de usar un símbolo (ficticio) en serializeBar.cpp (por ejemplo, llamando a una función ficticia implementado en serializeBar.cpp) antes de llamar a cualquier función de serialización para Foo*. El problema debería desaparecer.

Espero que ayude.

+0

3 años ... maldición! :RE – MOnsDaR

0

Difícil de decir ... Hay muchas posibilidades de que las cosas equivocarse. Recomiendo descargar el código de prueba para impulsar la serialización (www.boost.org/doc/libs/1_48_0/libs/serialization/test/). Eche un vistazo a los casos de prueba en torno a Ah, A.cpp y dll_a.cpp (que básicamente prueban su escenario) y trate de hacerlo funcionar fuera del sistema de prueba de refuerzo: use su entorno de compilación, intente modificar las opciones del compilador/enlazador para combine los de la suite de prueba de impulso para su conjunto de herramientas.

Honestamente, en mi humilde opinión, en algunos puntos, Boost serialización cruza la frontera de lo que es fiable posible con C++ puro construir el modelo w/o herramientas externas ...

1

el conjunto de pruebas y demostración distribuido con la biblioteca de serialización demuestran exactamente esta instalación. Así que primero asegúrate de que funcione. Luego compara tu ejemplo con eso.

Robert Ramey

"Honestamente, en mi humilde opinión, en algunos puntos, Boost serialización cruza la frontera de lo que es fiable posible con C++ puro construir el modelo w/o herramientas externas ..."

hmmmmmm - por lo cruza el huésped como lo que es posible? Sin embargo, eres bastante correcto en espíritu. Se hizo un gran esfuerzo para implementar todo lo que se consideró necesario para que un paquete así sea aceptado.

RR

0

Uso BOOST_CLASS_EXPORT para registrar todas sus clases que le gustaría para serializar

Cuestiones relacionadas