Проблема бинарной сериализации - PullRequest
3 голосов
/ 11 июня 2010

У меня проблема с использованием расширенной сериализации с использованием бинарных архивов. Это работает при использовании файлового потока, но я хочу сохранить его в моей локальной переменной и в конечном итоге сохранить / загрузить его в / из Беркли БД. При выполнении программы я получаю boost :: archive :: archive_exception : 'ошибка потока' при создании экземпляра binary_iarchive .

#include <sys/time.h>
#include <string>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>
#include <sstream>

namespace boost {
namespace serialization {

template<class Archive>
void serialize(Archive & ar, timeval & t, const unsigned int version)
{
    ar & t.tv_sec;
    ar & t.tv_usec;
}

}//namespace serialization
}//namespace boost


int main(int, char**)
{
    timeval t1;
    gettimeofday(&t1, NULL);
    char buf[256];

    std::stringstream os(std::ios_base::binary| std::ios_base::out| std::ios_base::in);
    {
        boost::archive::binary_oarchive oa(os, boost::archive::no_header);
        oa << t1;
    }

    memcpy(buf, os.str().data(), os.str().length());
    if(memcmp(buf, os.str().data(), os.str().length()) != 0)
        printf("memcpy error\n");

    timeval t2;
    {
        std::stringstream is(buf, std::ios_base::binary| std::ios_base::out| std::ios_base::in);

        boost::archive::binary_iarchive ia(is, boost::archive::no_header);
        ia >> t2;
    }

    printf("Old(%d.%d) vs New(%d.%d)\n", t1.tv_sec, t1.tv_usec, t2.tv_sec, t2.tv_usec);

    return 0;
}

Это работает, когда инициализация равна с os.str () , поэтому я предполагаю, что мой способ копирования данных в мой буфер или в неверен .

1 Ответ

9 голосов
/ 11 июня 2010

Ну, во-первых, у .data () нет терминала \ 0. Это не к-струна. Я даже не подозревал, что в stringstream есть конструктор char * (кто в здравом уме их использует?), Но, очевидно, он есть, и я готов поспорить, что он ожидает \ 0.

Почему вы пытаетесь сделать это так или иначе? Вам гораздо лучше работать в строках C ++. Инициализируйте с помощью os.str ().

Редактировать: двоичные данные содержат множество символов \ 0, и конструктор std :: string (char *) останавливается на первом. Ваша подпрограмма десериализации неизбежно будет пытаться прочитать после конца потока (потому что она не завершена). Используйте конструктор итератора для std :: string при передаче buf в поток строк.

std::stringstream is(std::string(buf, buf+os.str().length()), flags);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...