Сериализация Boost.Serialization по-разному на разных платформах?

Я использую 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 ответа

Решение

Попробуйте использовать text_iarchive а также text_oarchive вместо бинарных архивов. Из документации

В этом уроке мы использовали определенный архивный класс - text_oarchive для сохранения и text_iarchive для загрузки. текстовые архивы отображают данные в виде текста и переносимы между платформами. В дополнение к текстовым архивам библиотека включает в себя класс архива для собственных двоичных данных и данных в формате xml. Интерфейсы для всех классов архивов все идентичны. После определения сериализации для класса этот класс можно сериализовать в любой тип архива.

boost:archive::binary_xarchive в настоящее время не переносимы

С моей интерпретацией это означает, что могут быть различия на разных платформах. Текстовые архивы обеспечивают одинаковое поведение ввода / вывода во всех системах.
Также есть связанная запись TODO, которая пытается решить проблему переносимости двоичных архивов: Запись TODO

Производительность с text_archives на величины ниже, чем binary_archive. Если вам нужна производительность, вы можете попробовать неофициальный переносимый бинарный архив.eos_portable_archive, Я успешно использовал его для сериализации данных в 32- и 64-разрядных системах Windows. Вы можете попробовать.

Просто нужно поместить файлы в каталог для сериализации. Файлы там не обновлены до последней версии Boost (1.44.0), но вам просто нужно сделать 2 очень тривиальные корректировки, чтобы заставить его работать (ваш компилятор сообщит вам с очень очевидным сообщением об ошибке).

Я согласен с ответами, но хотел добавить пояснительную записку. Вы можете подумать, что это досадный недосмотр, но на самом деле придумать и реализовать переносимый двоичный формат не такая уж тривиальная задача. Единственный известный мне стандарт, который эффективно решает проблему в двоичном формате, - это ASN.1.

XML помогает решить ту же проблему, но обычно делает это в тексте. Существует дополнительный стандарт для XML, называемый Fast Infoset, который позволяет XML вместо этого кодировать данные в двоичном виде, но использует ASN.1.

Другие вопросы по тегам