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.

4

4 回答 4

16

尝试使用text_iarchiveandtext_oarchive而不是二进制档案。从文档

在本教程中,我们使用了一个特定的存档类 - text_oarchive 用于保存和 text_iarchive 用于加载。文本档案将数据呈现为文本,并且可以跨平台移植。除了文本存档之外,该库还包括原生二进制数据和 xml 格式数据的存档类。所有归档类的接口都是相同的。一旦为一个类定义了序列化,就可以将该类序列化为任何类型的存档。

于 2010-09-14T12:37:21.410 回答
9

boost:archive::binary_xarchive 目前不可移植

根据我的解释,这意味着不同平台上可能存在差异。文本存档在所有系统上为您提供相同的输入/输出行为。
还有一个相关的 TODO 条目试图解决二进制存档的可移植性问题:TODO 条目

于 2010-09-14T12:38:28.463 回答
7

text_archives 的性能比 binary_archive 慢很多。如果性能是你的事,你可以试试非官方的可移植二进制存档 eos_portable_archive。我已经用它在 Windows 上成功地序列化了 32 位和 64 位的数据。你可以试一试。

只需要将文件放在您的序列化目录中。那里的文件不是最新的 boost 版本(1.44.0),但您只需要进行 2 次非常微不足道的调整即可使其工作(您的编译器会告诉您非常明显的错误消息)。

于 2010-09-14T16:41:33.367 回答
3

我同意答案,但想添加一个澄清说明。您可能认为这是一个令人讨厌的疏忽,但实际上提出并实现可移植的二进制格式并不是一件容易的事。我知道有效解决二进制问题的唯一标准是ASN.1

XML 旨在解决相同的问题,但通常以文本形式进行。有一个名为Fast Infoset的 XML 搭载标准,它允许 XML 以二进制形式对数据进行编码,但它使用 ASN.1。

于 2010-09-14T12:59:08.437 回答