2010-09-14 28 views
12

Utilizo Boost.Serialization para serializar un std :: map. El código es el siguiente¿Boost.Serialization se serializa de manera diferente en diferentes plataformas?

void Dictionary::serialize(std::string & buffer) 
{ 
    try { 
    std::stringstream ss; 
    boost::archive::binary_oarchive archive(ss); 
    archive << dict_; 
    buffer = ss.str(); 
    } catch (const std::exception & ex) { 
    throw DictionaryException(ex.what()); 
    } 
} 

void Dictionary::deserialize(const char * const data, int length) 
{ 
    try { 
    namespace io = boost::iostreams; 
    io::array_source source(data, length); 
    io::stream<io::array_source> in(source); 
    boost::archive::binary_iarchive archive(in); 
    archive >> dict_; 
    } catch (const std::exception & ex) { 
    throw DictionaryException(ex.what()); 
    } 
} 

I compilado y probado el código en un Mac Snow Leopard y en Ubuntu Lucid 10.04. Hay Boost 1.40 en ambos sistemas. En la Mac, construí el código yo mismo. En el cuadro de Ubuntu obtuve los binarios a través de aptitude.

Problema: Cuando serializo el mapa en la Mac no puedo deserializarlo en la caja de Ubuntu. Obtengo una excepción de firma inválida si lo intento.

Respuesta

15

intente utilizar un text_iarchive y text_oarchive en lugar de archivos binarios. Desde el documentation

En este tutorial, hemos utilizado una clase particular, archivo - text_oarchive para el ahorro y text_iarchive para la carga. Los archivos de texto representan los datos como texto y son portátiles en todas las plataformas. Además de para archivos de texto, la biblioteca incluye clase de archivo para datos binarios nativos y datos formateados xml. Las interfaces a todas las clases de archivo son todas idénticas. Una vez que se ha definido la serialización para una clase, esa clase puede ser serializada en cualquier tipo de archivo.

+5

Tenga en cuenta que esto podría tener un efecto muy significativo en el rendimiento de la aplicación. –

9

impulso: Archivo :: binary_xarchive son actualmente no portátil

Con mi interpretación eso significa que no puede haber diferencias en las diferentes plataformas. Los archivos de texto le dan el mismo comportamiento de entrada/salida en todos los sistemas.
También hay una entrada TODO relacionado que trata de resolver el problema de la portabilidad de los archivos binarios: TODO Entry

3

Estoy de acuerdo con las respuestas, pero quería añadir una nota aclaratoria. Puede pensar que esto es una supervisión molesta, pero de hecho idear e implementar un formato binario portátil no es una tarea tan trivial. El único estándar que conozco que aborda eficazmente el problema en el código binario es ASN.1.

Prrutes XML para abordar el mismo problema, pero generalmente lo hace en el texto. Hay un estándar para XML llamado Fast Infoset que permite que XML codifique los datos en forma binaria, pero usa ASN.1.

+0

Wow. No estoy seguro de haber escuchado "efectivamente" y "ASN.1" tan cerca el uno del otro. Pero luego, una vez tuve que depurar un ASN.1 analizador que alguien más había escrito, por lo que tiendo a asociarlo con horas de agonía insoportable. Puede que en realidad no sea la falla de ASN.1. –

+0

No discuto. Que es mi culpa. Debería haber leído los documentos de Boost.Serialization. El texto está bien. –

+0

@Steve Jessop - No es su culpa en absoluto, pero creo que es principalmente la culpa de la tarea. Probablemente existan analizadores de ASN.1 generales, pero todos los que he visto solo analizan el subconjunto de ASN.1 que espera de quien sea el otro lado. Incluso esa es una tarea peluda. –

7

El rendimiento con text_archives es las magnitudes más lentas que binary_archive. Si lo tuyo es el rendimiento, puedes probar an unofficial portable binary archiveeos_portable_archive. Lo he usado para serializar datos en 32 bit y 64 bit en Windows con éxito. Puedes intentarlo.

Solo necesita colocar los archivos en su directorio de serialización. Los archivos no están actualizados con la última versión de boost (1.44.0), pero solo necesitas hacer 2 ajustes muy triviales para que funcione (tu compilador te avisará con un mensaje de error muy obvio).

+1

'eos_portable_archive' no admite la serialización de wstrings, que para mí rompió el trato. Hay un portable_binary_iarchive.hpp que viene con boost (en el boost/libs/serialization/example) que no tiene esta limitación, y funcionó bien para mí. Tiene algunas otras limitaciones [documentadas aquí] (http://www.boost.org/doc/libs/1_47_0/libs/serialization/doc/todo.html#portablebinaryarchives) –

+0

@Omer Raviv: el archivo portátil no es compatible serializar tipos de punto flotante, lo cual fue un problema para mí en ese punto. De hecho, me di cuenta de que 'boost :: serialization' [agrega un tamaño horrible] (http://lists.boost.org/boost-users/2010/09/63015.php) al ejecutable que lo abandoné y rodé el mío . No estoy seguro de si las versiones más nuevas de boost han solucionado eso. – kizzx2

+3

** ACTUALIZACIÓN: ** El archivo portátil EOS v5.0 ahora [admite wstring] (http://epa.codeplex.com/releases/view/91073) también. El nuevo hogar es [aquí] (http://epa.codeplex.com/). –

Cuestiones relacionadas