2011-02-23 9 views
5

tengo una clase y yo estoy tratando de serializar un shared_ptr pero el método normal de la serialización de un objeto no está funcionando:Boost C++ serializar un char *

class Object { 
public: 
    Object(); 
    ~Object(); 

    shared_ptr<char>objectone; 

    friend class boost::serialization::access; 
    template <typename Archive> 
    void serialize(Archive &ar, const unsigned int version) 
    { 
     ar & objectone; 
    } 
}; 

incluso he intentado de esta manera, pero todavía no funciona:

void serialize(Archive &ar, const unsigned int version) 
    { 
     for (int i = 0; i < (strlen(objectone.get())); i++) 
      ar & objectone.get()[i]; 
    } 

¿Alguna idea de cómo abordar esto? Gracias.

Alguna información adicional:

ya he incluido dos archivos de cabecera shared_ptr:

#include <boost/serialization/shared_ptr.hpp> 
#include <boost/serialization/shared_ptr_132.hpp> 

he intentado convertir en una cadena y serializarlo de esa manera pero produce el siguiente error : impulso :: artículos :: archive_exception' lo que(): flujo de error

friend class boost::serialization::access; 
template <typename Archive> 
void serialize(Archive &ar, const unsigned int version) 
{ 
    if (objectone.get()) { 
     string temp(objectone.get()); 
     ar & temp; 
    } 
    ar & objectone; 
} 
+0

shared_ptr no hace lo que parece pensar que hace. No puedes tratarlo como una cadena porque no es una cadena. Es un puntero inteligente para un solo personaje. – Alan

Respuesta

2

Faltan algunos conceptos clave. Ya no necesitas share_ptr si usas std :: string.

Usted puede hacer

class Object { 
public: 
    Object(); 
    ~Object(); 

    std::string name; 

    template <typename Archive> 
    void serialize(Archive &ar, const unsigned int version) 
    { 
     ar & name; 
    } 
}; 

y ya está.

adición

Teniendo en cuenta sus necesidades esto es lo que tiene que hacer

class test 
{ 
public: 

friend class boost::serialization::access; 

test() 
{  
} 

template<class Archive> 
void save(Archive & ar, const unsigned int version) const 
{ 
    int len = strlen(data.get()); 
    ar & len; 
    for (int index = 0; index < len; ++index) 
     ar & data[index];  
} 
template<class Archive> 
void load(Archive & ar, const unsigned int version) 
{ 
    int len = 0; 
    ar & len; 
    data = boost::shared_array<char>(new char[len+1]); 
    for (int index = 0; index < len; ++index) 
     ar & data[index]; 
    data[len] = 0; 
} 
BOOST_SERIALIZATION_SPLIT_MEMBER() 

boost::shared_array<char> data; 
}; 
+0

Gracias por el código auxiliar. :) Como mencioné en el comentario de crazy. No tengo la flexibilidad de cambiar mis variables de miembro a cadenas, pero intenté una conversión de cadena en mi método de serialización que produjo un error. No estoy seguro de si ese era el enfoque correcto ya que esta es mi primera experiencia con el impulso. Un punto en la dirección correcta será muy apreciado. Gracias. – user459811

4

Hay más de un pr oblema con tu código.

En primer lugar, shared_ptr no está destinado a contener matrices. Para de hacer eso.

En segundo lugar, la biblioteca de serialización no guarda las cadenas estilo C que conozco. Sería bastante difícil de implementar y básicamente inútil ya que puedes guardar vector o string, que es lo que deberías usar de todos modos.

Si realmente insiste en mantener una cadena char*, entonces necesita convertirla en vector/string, y guardarla. Luego, al leer, necesitas leer el vector/string, obtener el tamaño, asignar la memoria, pegarla ... etc ... El seguimiento del puntero no funcionará, así que si confías en eso, tendrás que implementar usted mismo Que te diviertas.

Nuevo código de edición:

Estás haciendo el bit de salvamento en una función que cubre tanto la parada de carga. Por supuesto, no funciona muy bien cargando wrt. Debes dividir tu serialización. if (Archive::is_saving) tampoco funcionará. La documentación de impulso explica cómo dividir correctamente la rutina de serialización.

+1

+1 Convierta su 'char *' a 'std :: string'. – karlphillip

+0

No tengo la flexibilidad de cambiar mis variables de miembro a cadenas, pero intenté una conversión de cadena que produjo un error. ¿Alguien me puede apuntar en la dirección correcta? La pregunta ha sido editada para incluir el código anterior. Gracias. – user459811

4

Tenga en cuenta lo que dijo acerca de Eddie el Loco shared_ptr no ser la herramienta adecuada para el trabajo. Como no tiene la flexibilidad para cambiar la definición de la clase, aquí hay una solución alternativa.

boost :: serialization proporciona un contenedor make_array que toma un puntero y lo envuelve como una matriz para la serialización. Esto requiere que el tamaño de la matriz sea conocido antes de la serialización.

A continuación, podría hacer algo como:

void serialize(Archive &ar, const unsigned int version) 
{ 
    ar & array_size; // Figure out how to determine this (perhaps strlen(objectone.get()) 

    if (ar::is_loading) 
    { 
     objectone.reset(new char[array_size]); // allocate the array before we load it 
    } 

    if (objectone.get() != NULL) 
    { 
     ar & make_array(objectone.get(), array_size); 
    } 
} 

Ese ejemplo de código es bastante rudimentario, pero transmite el concepto.

+0

Estoy intentando esto con 'archive & boost :: serialization :: make_array' pero obteniendo" make_array no es miembro de boost :: serialization ". ¿Qué más necesito incluir aparte de #include ? –

+0

@DavidDoria Creo que necesita incluir para obtener boost :: serialization :: make_array. – tallganglyguy