14

I use Boost.Serialization to serialize a std::map. The code looks like this

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 compiled and tested the code on a Mac Snow Leopard and on Ubuntu Lucid 10.04. There is Boost 1.40 on both systems. On the Mac I built the code myself. On the Ubuntu box I got the binaries via aptitude.

Problem: When I serialize the map on the Mac I can't deserialize it on the Ubuntu box. I get an invalid signature exception if I try.

Jan Deinhard
  • 19,645
  • 24
  • 81
  • 137

4 Answers4

16

try using a text_iarchive and text_oarchive instead of binary archives. From the documentation

In this tutorial, we have used a particular archive class - text_oarchive for saving and text_iarchive for loading. text archives render data as text and are portable across platforms. In addition to text archives, the library includes archive class for native binary data and xml formatted data. Interfaces to all archive classes are all identical. Once serialization has been defined for a class, that class can be serialized to any type of archive.

Sam Miller
  • 23,808
  • 4
  • 67
  • 87
9

boost:archive::binary_xarchive are currently not portable

With my interpretation that means that there can be differences on different platforms. The text archives gives you the same input/output behaviour on all systems.
Also there is a related TODO entry which tries to solve the portability issue of the binary archives: TODO Entry

Daniel
  • 2,993
  • 2
  • 23
  • 40
7

The performance with text_archives is magnitudes slower than binary_archive. If performance is your thing, you may try out an unofficial portable binary archive eos_portable_archive. I've used it to serialize data across 32 bit and 64 bit on Windows with success. You may give it a go.

Just need to put the files in your serialization directory. The files there are not up to date with the latest boost version (1.44.0) but you just need to make 2 very trivial adjustments to make it work (your compiler will tell you with very obvious error message).

kizzx2
  • 18,775
  • 14
  • 76
  • 83
  • 1
    `eos_portable_archive` doesn't support serializing wstrings, which for me broke the deal. There is a portable_binary_iarchive.hpp that comes with boost (in the boost/libs/serialization/example) which doesn't have this limitation, and worked fine for me. It has some other limitations [documented here](http://www.boost.org/doc/libs/1_47_0/libs/serialization/doc/todo.html#portablebinaryarchives) – Omer Raviv Oct 29 '11 at 18:10
  • @Omer Raviv: The portable archive doesn't support serializing floating point types, which was broken deal for me at that point. In fact I realized that `boost::serialization` [adds horrendous size](http://lists.boost.org/boost-users/2010/09/63015.php) to the executable that I abandoned it and rolled my own. I am not sure if newer versions of boost have fixed that. – kizzx2 Oct 30 '11 at 06:22
  • 3
    **UPDATE:** EOS portable archive v5.0 now [supports wstring](http://epa.codeplex.com/releases/view/91073) as well. New home is [here](http://epa.codeplex.com/). – Adi Shavit May 22 '13 at 08:51
3

I agree with the answers, but wanted to add a clarifying note. You might think this is an annoying oversight, but in fact coming up with and implementing a portable binary format is not such a trivial task. The only standard that I'm aware of that effectively tackles the problem in binary is ASN.1.

XML pruports to tackle the same problem, but generally does it in text. There's a piggyback standard for XML called Fast Infoset that allows XML to encode the data in binary form instead, but it uses ASN.1.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • Wow. Not sure I've ever heard "effectively" and "ASN.1" so close together before. But then, I did once have to debug an ASN.1 parser that someone else had written, so I tend to associate it with hours of excruciating agony. May not actually be ASN.1's fault. – Steve Jessop Sep 14 '10 at 13:02
  • I don't argue. It's my fault. I should've read the Boost.Serialization docs. Text is just fine. – Jan Deinhard Sep 14 '10 at 13:03
  • @Steve Jessop - Not your fault at all, but I think its mostly the task's fault. There are probably some general ASN.1 parsers out there, but every one I have ever seen just parses the subset of ASN.1 that it expects out of whoever the other side is. Even that is a hairy task. – T.E.D. Sep 14 '10 at 16:04
  • no doubt this was the case for the parser I was debugging. It was only being used for X.509 certificates and related entities. – Steve Jessop Sep 14 '10 at 16:20