I’m trying to serialize an object using boost serialization. Everything works perfectly if I use a text_archive, I can serialize, deserialize back, and everything is in its place. I tried to serialize with a binary archive, with mixed result. If I use a boost array_sink, connected to a char buffer, everything works smootly. If I change to a dynamically allocated buffer, the serialization fails, and the corresponding vector is left empty.
I found many examples of people using a iostream with back inserter, and nobody had such a problem.
Here is an example that give me the error:
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream.hpp>
#include <cassert>
#include <iostream>
class MyClass
{
public:
MyClass(int myVar) : _myVar(myVar) {}
MyClass() {}
int _myVar = 0;
friend bool operator== (const MyClass& c1, const MyClass& c2)
{
return c1._myVar == c2._myVar;
}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int/* version*/)
{
ar & _myVar;
}
};
int main(int, char**)
{
std::shared_ptr<MyClass> srcPtr(new MyClass(42));
std::shared_ptr<MyClass> dstPtr;
std::cout << "Serialize using stringstream and text archive" << std::endl;
std::stringstream oss;
boost::archive::text_oarchive toa(oss);
toa << srcPtr;
std::cout << oss.str() << std::endl;
std::stringstream iss(oss.str());
boost::archive::text_iarchive tia(iss);
tia >> dstPtr;
assert(*srcPtr == *dstPtr);
std::cout << "Dest var is: " << dstPtr-> _myVar << std::endl;
dstPtr.reset();
std::cout << "Done" << std::endl;
//Static buffer and binary
std::cout << "Serialize using static buffer and binary archive" << std::endl;
char testBuffer[4096];
boost::iostreams::stream<boost::iostreams::array_sink> static_os(testBuffer);
boost::archive::binary_oarchive static_oa(static_os);
static_oa << srcPtr;
std::cout << "Static buffer, buffer size: " << static_os.tellp() << std::endl;
boost::iostreams::stream<boost::iostreams::array_source> static_is(testBuffer);
boost::archive::binary_iarchive static_ia(static_is);
static_ia >> dstPtr;
assert(*srcPtr == *dstPtr);
std::cout << "Dest var is: " << dstPtr-> _myVar << std::endl;
dstPtr.reset();
std::cout << "Done" << std::endl;
//Dynamic vector
std::cout << "Serialize using dynamic buffer and binary archive" << std::endl;
std::vector<char> buffer;
boost::iostreams::stream obs(boost::iostreams::back_inserter(buffer));
boost::archive::binary_oarchive oba(obs);
oba << srcPtr;
std::cout << "BufferSize: " << buffer.size() << std::endl;
boost::iostreams::stream<boost::iostreams::array_source> ibs(buffer.data(),buffer.size());
boost::archive::binary_iarchive iba(ibs);
iba >> dstPtr;
assert(*srcPtr == *dstPtr);
std::cout << "Dest var is: " << dstPtr-> _myVar << std::endl;
dstPtr.reset();
std::cout << "Done" << std::endl;
}
The output is
Serialize using stringstream and text archive
22 serialization::archive 18 0 1 1 1 0
0 42
Dest var is: 42
Done
Serialize using static buffer and binary archive
Static buffer, buffer size: 60
Dest var is: 42
Done
Serialize using dynamic buffer and binary archive
BufferSize: 0
terminate called after throwing an instance of 'boost::wrapexcept<std::ios_base::failure[abi:cxx11]>'
what(): no read access: iostream error
Aborted (core dumped)