2010-06-11 5 views
3

이진 아카이브를 사용하여 부스트 직렬화를 사용하는 데 문제가 있습니다. 파일 스트림을 사용할 때 작동하지만 로컬 변수에 저장하고 궁극적으로 berkeley db에로드/저장합니다. 프로그램을 실행할 때 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(), 그래서 난 내 버퍼에 데이터를 복사하는 내 방식을 추측하거나 잘못이다.

답변

9

글쎄, 한가지 .data()에는 터미널 \ 0이 없습니다. 그것은 C 문자열이 아닙니다. 나는 stringstream이 char * 생성자를 가지고 있다는 것을 깨닫지 못했다. (누가 올바른 생각을 가지고 있 었는가?) 분명히 그렇지만 나는 0을 기대한다.

어쨌든 왜 그렇게하려고합니까? C++ 문자열로 작업하는 것이 훨씬 낫습니다. 초기화는 os.str()로합니다.

편집 : 이진 데이터에는 \ 0 문자가 많이 포함되어 있으며 std :: string (char *) 생성자는 처음부터 중지됩니다. 그런 다음 deserialization 루틴은 필연적으로 스트림의 끝을 지나쳐 읽으려고 시도합니다 (완료되지 않았기 때문에). buf를 문자열 스트림에 전달할 때 std :: string에 대한 반복자 생성자를 사용하십시오.

std::stringstream is(std::string(buf, buf+os.str().length()), flags); 
+0

이미 C 문자열을 사용하려고했으나 작동하지 않았습니다. 버클리 DB에 원시 데이터를 저장해야하기 때문에 C++ 문자열을 사용하지 않습니다. 직렬화 된 데이터를 버클리 db에 저장 한 다음 나중에 검색하고 직렬화 해제하는 것이 그 목적입니다. – user364688

+3

나는 정확했다. stringstream에는 문자열이 아닌 생성자가 없습니다. 코드가 암시 적 캐스팅을 통해 코드를 만들려고합니다. buf 대신에 std :: string (buf, buf + os.str(). length())을 전달하여 명시 적으로 캐스팅을 시도 할 수 있습니다. std :: string에 대한 char * 생성자가 * first * \ 0에서 멈추고 바이너리 데이터가 아마도 그것들로 가득 차 있기 때문에 문제가 해결됩니다. –

+0

작품, 도움 주셔서 감사합니다! – user364688