2010-06-10 16 views
20

Los documentos de serialización de refuerzo afirman que la forma de serializar/deserializar los elementos es utilizar un archivo binario/de texto con una secuencia en la estructura subyacente. Esto funciona bien si no quiero utilizar los datos serializados como std :: string, pero mi intención es convertirlo directamente en un búfer char *. ¿Cómo puedo lograr esto sin crear una cadena temporal?serialización de refuerzo directo a la matriz de caracteres

¡Resuelto! Para los que querían un ejemplo:

char buffer[4096]; 

boost::iostreams::basic_array_sink<char> sr(buffer, buffer_size); 
boost::iostreams::stream< boost::iostreams::basic_array_sink<char> > source(sr); 

boost::archive::binary_oarchive oa(source); 

oa << serializable_object; 
+0

Por otro lado, ¿por qué renunciar a la gestión de memoria libre y la fuga de riesgo y desbordamiento :)? –

+0

Lamentablemente, debido a problemas de rendimiento :( – scooterman

Respuesta

6

IIUC, le gustaría escribir en una matriz preasignada de tamaño fijo.

Puede usar un boost::iostreams::array_sink (envuelto con stream para darle una interfaz std :: ostream) para eso.

+0

@op: ¡Gracias, eso funcionó como un amuleto! Solo quería que ese impulso tuviera más documentación :( – scooterman

31

Si no se conoce el tamaño de los datos que va a enviar por adelantado, esto es una forma genérica para serializar en un std::string:

// serialize obj into an std::string 
std::string serial_str; 
boost::iostreams::back_insert_device<std::string> inserter(serial_str); 
boost::iostreams::stream<boost::iostreams::back_insert_device<std::string> > s(inserter); 
boost::archive::binary_oarchive oa(s); 

oa << obj; 

// don't forget to flush the stream to finish writing into the buffer 
s.flush(); 

// now you get to const char* with serial_str.data() or serial_str.c_str() 

deserializar, utilice

// wrap buffer inside a stream and deserialize serial_str into obj 
boost::iostreams::basic_array_source<char> device(serial_str.data(), serial_str.size()); 
boost::iostreams::stream<boost::iostreams::basic_array_source<char> > s(device); 
boost::archive::binary_iarchive ia(s); 
ia >> obj; 

Este funciona como un encanto, lo utilizo para enviar datos con MPI.

Esto se puede hacer muy rápido si mantiene el serial_str en memoria, y simplemente llame al serial_str.clear() antes de serializarlo en él. Esto borra los datos pero no libera ninguna memoria, por lo que no se realizará ninguna asignación cuando su próximo tamaño de datos de serialización no lo requiera.

+0

¡Gran respuesta! Estoy intentando mantener el búfer en la memoria como sugieres, pero parece que llamar a serial_str.clear() no es suficiente. ¿Debo reiniciar a binary_orachive o al back_inserter_device de alguna manera, para decirle que regrese a la escritura al comienzo de serial_str? –

+0

@omer, en mi código que acabo de escribir 'std :: string serial_str' como variable miembro, y vuelva a crear todo lo demás cada vez que envíe algo. – martinus

+0

Esta solución es lo que estaba buscando. ¡Gracias! – aardvarkk

Cuestiones relacionadas