不同平台上,Boost.Serialization的序列化是否不同?

14

我使用 Boost.Serialization 序列化一个 std::map。代码如下:

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

我在Mac Snow Leopard和Ubuntu Lucid 10.04上编译并测试了代码,两个系统都有Boost 1.40。在Mac上我自己构建了代码,在Ubuntu上我通过aptitude获得了二进制文件。

问题:当我在Mac上序列化地图时,我无法在Ubuntu上反序列化它。如果我尝试,会出现无效签名异常。

4个回答

16

尝试使用 text_iarchivetext_oarchive 代替二进制存档。来自文档

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


5
请注意,这可能会对您的应用程序性能产生非常重要的影响。 - Omer Raviv

9

boost:archive::binary_xarchive目前不具备可移植性。

我的理解是,在不同平台上可能会有差异。文本存档可以在所有系统上提供相同的输入/输出行为。
此外,还有一个相关的TODO条目,试图解决二进制存档的可移植性问题:TODO Entry


7
使用text_archives的性能比binary_archive慢得多。如果您注重性能,可以尝试非官方便携式二进制归档 eos_portable_archive。我已经成功地在Windows上跨32位和64位序列化数据时使用它。您可以试一试。
只需要将文件放在序列化目录中即可。那里的文件不是最新的boost版本(1.44.0),但您只需要做两个非常微小的调整就可以使其正常工作(您的编译器会告诉您非常明显的错误消息)。

1
eos_portable_archive不支持对wstrings进行序列化,这对我来说是个问题。Boost附带了一个portable_binary_iarchive.hpp(位于boost/libs/serialization/example),它没有这个限制,并且对我来说工作得很好。它还有一些其他限制,在这里有详细记录 - Omer Raviv
@Omer Raviv:可移植存档不支持序列化浮点类型,这对我来说是个致命的问题。事实上,我意识到boost::serialization会使可执行文件的大小变得非常大,所以我放弃了它并自己编写了一个。我不确定新版本的boost是否已经解决了这个问题。 - kizzx2
3
更新:EOS可移植档案v5.0现在也支持wstring。新主页在这里 - Adi Shavit

3

我同意之前的回答,但是想要补充一些澄清的内容。你可能认为这是一个令人烦恼的疏忽,但实际上设计和实现一个可移植的二进制格式并非易事。在我所知道的标准中,唯一有效解决这个问题的是ASN.1

XML试图解决同样的问题,但通常采用文本方式。有一个名为Fast Infoset的XML附加标准可以将数据以二进制形式编码,但它使用了ASN.1。


哇,我不确定我以前是否听过“有效地”和“ASN.1”这么紧密地联系在一起。但是,我曾经不得不调试别人编写的ASN.1解析器,所以我倾向于将其与数小时的极度痛苦联系在一起。这可能并不是ASN.1的错。 - Steve Jessop
我不争辩。这是我的错。我应该读一下Boost.Serialization文档。这段文字没问题。 - Jan Deinhard
@Steve Jessop - 这完全不是你的错,但我认为这主要是任务的问题。可能有一些通用的ASN.1解析器存在,但我见过的每一个都只解析它期望从另一侧得到的ASN.1子集。即使那也是一个棘手的任务。 - T.E.D.
毫无疑问,这就是我正在调试的解析器的情况。它仅用于X.509证书和相关实体。 - Steve Jessop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接