2010-09-14 11 views
12

Uso Boost.Serialization per serializzare una std :: map. Il codice è simile al seguenteLa serializzazione Boost serializza in modo diverso su piattaforme diverse?

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()); 
    } 
} 

ho compilato e testato il codice su un Mac Snow Leopard e su Ubuntu Lucid 10.04. C'è Boost 1.40 su entrambi i sistemi. Sul Mac ho costruito il codice da solo. Sulla scatola di Ubuntu ho ottenuto i binari tramite aptitude.

Problema: quando serializzo la mappa su Mac, non posso deserializzarla nella finestra di Ubuntu. Riceverò l'eccezione della firma non valida se provo.

risposta

15

provare a utilizzare uno text_iarchive e text_oarchive invece di archivi binari. Dal documentation

In questo tutorial, abbiamo utilizzato una classe particolare archivio - text_oarchive per il salvataggio e text_iarchive per il caricamento. gli archivi di testo riproducono i dati come testo e sono portatili tra piattaforme. Inoltre per gli archivi di testo, la libreria include la classe di archivio per i dati binari nativi e i dati formattati xml. Interfacce su tutte le classi di archivio sono tutte identiche. Una volta definita la serializzazione per una classe, tale classe può essere serializzata su qualsiasi tipo di archivio. .

+5

Si noti che questo potrebbe avere un effetto molto significativo sulle prestazioni dell'applicazione. –

9

spinta: archivio :: binary_xarchive è finita portatili

con la mia interpretazione che significa che ci possono essere differenze su diverse piattaforme. Gli archivi di testo offrono lo stesso comportamento di input/output su tutti i sistemi.
Inoltre v'è una voce TODO collegato che cerca di risolvere il problema di portabilità degli archivi binari: TODO Entry

3

Sono d'accordo con le risposte, ma ha voluto aggiungere una nota chiarificatrice. Si potrebbe pensare che questo sia un fastidioso svista, ma in effetti inventarsi e implementare un formato binario portatile non è un compito così banale. L'unico standard di cui sono a conoscenza che risolve efficacemente il problema in binario è ASN.1.

XML prenuncia per affrontare lo stesso problema, ma generalmente lo fa nel testo. C'è uno standard piggyback per XML chiamato Fast Infoset che consente al codice XML di codificare i dati in formato binario, ma utilizza ASN.1.

+0

Wow. Non sono sicuro di aver mai sentito "efficacemente" e "ASN.1" così vicini. Ma poi, una volta ho dovuto eseguire il debug di un ASN.1 parser che qualcun altro ha scritto, quindi tendo ad associarlo a ore di straziante agonia. Potrebbe non essere effettivamente colpa di ASN.1. –

+0

Non discuto. È colpa mia. Avrei dovuto leggere i documenti Boost.Serialization. Il testo va bene. –

+0

@Steve Jessop - Non è affatto colpa tua, ma penso che sia principalmente colpa del compito. Ci sono probabilmente alcuni parser generali ASN.1, ma tutti quelli che ho visto analizzano solo il sottoinsieme di ASN.1 che si aspetta da chiunque sia l'altro lato. Anche quello è un compito peloso. –

7

Le prestazioni con text_archives sono più lente di binary_archive. Se le prestazioni sono la tua passione, puoi provare an unofficial portable binary archiveeos_portable_archive. L'ho usato per serializzare i dati su 32 bit e 64 bit su Windows con successo. Puoi provarlo.

Basta inserire i file nella directory di serializzazione. I file non sono aggiornati con l'ultima versione di boost (1.44.0), ma devi solo fare 2 aggiustamenti molto banali per farlo funzionare (il tuo compilatore ti dirà con un messaggio di errore molto ovvio).

+1

'eos_portable_archive' non supporta la serializzazione delle stringhe, che per me ha rotto l'accordo. C'è un portable_binary_iarchive.hpp che viene fornito con boost (in boost/libs/serialization/example) che non ha questa limitazione, e ha funzionato bene per me. Ha alcune altre limitazioni [documentate qui] (http://www.boost.org/doc/libs/1_47_0/libs/serialization/doc/todo.html#portablebinaryarchives) –

+0

@Omer Raviv: l'archivio portatile non supporta serializzare i tipi in virgola mobile, che a quel punto era un affare rotto per me. In effetti ho capito che 'boost :: serialization' [aggiunge dimensioni orrende] (http://lists.boost.org/boost-users/2010/09/63015.php) all'eseguibile che l'ho abbandonato e ho fatto il mio . Non sono sicuro che le nuove versioni di boost abbiano risolto questo problema. – kizzx2

+3

** AGGIORNAMENTO: ** EOS portable archive v5.0 ora [supporta wstring] (http://epa.codeplex.com/releases/view/91073) pure. La nuova casa è [qui] (http://epa.codeplex.com/). –

Problemi correlati