Сериализация 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.