What is the maximum size a Boost Message Queue can Handle?
When I am sending and receiving the below structure by using Boost binary serialization it is working fine.
typedef struct {
int msg_type;
char msg_name[100];
union {
struct {
int ID;
std::string ReportedTime;
char ReceivedAt[200];
int Number;
int Priority;
} mess1;
struct {
char host_ip[20];
char mac_addr[30];
char time_stamp[100];
} mess2;
} struct_type;
}msg_struct;
#include <boost/serialization/is_bitwise_serializable.hpp>
BOOST_IS_BITWISE_SERIALIZABLE(msg_struct)
But when I making the size of ReceivedAt[2000] to 2000 or adding a new char array variable.
It is throwing the following exception and the core is getting dumped.
terminate called after throwing an instance of 'boost::interprocess::interprocess_exception'
what(): boost::interprocess_exception::library_error
Aborted (core dumped)
Edit
Send
int ControlQueue::pushMessage(msg_struct* msg)
{
int q_size = vamsgq->get_num_msg();
int retVal = 0;
lockQueue();
//imp->ID=1;
//strcpy(imp->ReceivedAt,"10-07-14");
std::stringstream oss;
boost::archive::binary_oarchive oa(oss);
strncpy(msg->msg_name,"msg_name",sizeof(msg->msg_name));
oa << boost::serialization::make_array(msg, 1);
std::string serialized_string(oss.str());
vamsgq->send(serialized_string.data(), serialized_string.size(), 0);
std::cout <<"\n sendig type="<< msg->msg_name << std::endl;
if((retVal = pthread_cond_signal(&m_qCondSignal)) != 0)
{
cout<<__FILE__<<__LINE__<<
"{ControlQueue %x} Unable to send Cond Signal",this);
}
unlockQueue();
return 1;
}
Recieve:
msg_struct* ControlQueue::getMsg()
{
int retVal = 0;
message_queue::size_type recvd_size;
unsigned int priority;
lockQueue();
while(vamsgq->get_num_msg()==0)
{
if((retVal = pthread_cond_wait(&m_qCondSignal, &m_qMutex)) != 0)
{
cout<<__FILE__<<__LINE__<<"getMsg {ControlQueue } Unable to Cond Signal";
unlockQueue();
return NULL;
}
}
msg_struct *l_msg_struct = NULL;
if(vamsgq->get_num_msg())
{
l_msg_struct=new msg_struct();
std::stringstream iss;
std::string serialized_string;
serialized_string.resize(MAX_SIZE);
vamsgq->receive(&serialized_string[0], MAX_SIZE, recvd_size, priority);
iss << serialized_string;
boost::archive::binary_iarchive ia(iss);
ia >> boost::serialization::make_array(l_msg_struct, 1);
std::cout <<"Recieving="<< l_msg_struct->msg_name << std::endl;
}
else
{
cout<<__FILE__<<__LINE__<<"getMsg {ControlQueue } m_MsgQ empty..";
}
unlockQueue();
return l_msg_struct;
}
The Send and Receive both are running in different threads the only problem what I am getting is after increasing the size of structure or adding an char array variable.
And the exception is getting thrown by the vamsgq->send() method, Creation method(message queue) is working fine. And I am also increasing the size of Message that message queue is going to store.
Is there any complete documentation online for the boost::message_queue.
You broke the requirement for
BOOST_IS_BITWISE_SERIALIZABLE(msg_struct)
by no longer keeping the msg_struct a POD type:
static_assert(boost::is_pod<msg_struct>::value, "msg_struct must be POD");
will fail to compile. (In fact, with the msg_struct shown using std::string, I think default construction should fail to compile, so the new msg_struct() line in your example confuses me).
Also you don't show the construction of the message-queue, so I can't tell how you determine the maximum message size. This might be inadequately dimensioned. See below for two approaches that use/check the size limitations.
Here's what would work:
[Solution A] All POD data, no serialization
#include <boost/serialization/serialization.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>
typedef struct {
int msg_type;
char msg_name[100];
union {
struct {
int ID;
char ReportedTime[100];
char ReceivedAt[2000];
int Number;
int Priority;
} mess1;
struct {
char host_ip[20];
char mac_addr[30];
char time_stamp[100];
} mess2;
} struct_type;
} msg_struct;
static_assert(boost::is_pod<msg_struct>::value, "msg_struct must be POD");
#include <boost/serialization/is_bitwise_serializable.hpp>
BOOST_IS_BITWISE_SERIALIZABLE(msg_struct)
namespace ipc = boost::interprocess;
int main() {
ipc::message_queue queue(ipc::open_or_create, "myqueue", 100, sizeof(msg_struct));
msg_struct outgoing;
outgoing.msg_type = 1;
strncpy(outgoing.msg_name, "outgoing.msg_name", sizeof(outgoing.msg_name));
outgoing.struct_type.mess1.ID = 42;
strncpy(outgoing.struct_type.mess1.ReportedTime, "outgoing.struct_type.mess1.ReportedTime", sizeof(outgoing.struct_type.mess1.ReportedTime));
strncpy(outgoing.struct_type.mess1.ReceivedAt, "outgoing.struct_type.mess1.ReceivedAt", sizeof(outgoing.struct_type.mess1.ReceivedAt));
outgoing.struct_type.mess1.Number = 123;
outgoing.struct_type.mess1.Priority = 234;
queue.send(&outgoing, sizeof(outgoing), 1);
}
As you can see, this is not using Boost Serialization because the struct is POD anyways.
[Solution B] Highlevel C++ types, using binary serialization
Alternatively, you can use Boost Serialization all the way and check that the message size doesn't exceed the maximum message size when sending:
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/variant.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>
typedef struct {
int msg_type;
std::string msg_name;
struct mess1_t {
int ID;
std::string ReportedTime;
std::string ReceivedAt;
int Number;
int Priority;
private:
friend class boost::serialization::access;
template <typename Ar>
void serialize(Ar& ar, unsigned)
{
ar & ID;
ar & ReportedTime;
ar & ReceivedAt;
ar & Number;
ar & Priority;
}
};
struct mess2_t {
std::string host_ip;
std::string mac_addr;
std::string time_stamp;
private:
friend class boost::serialization::access;
template <typename Ar>
void serialize(Ar& ar, unsigned)
{
ar & host_ip;
ar & mac_addr;
ar & time_stamp;
}
};
boost::variant<mess1_t, mess2_t> message_data;
private:
friend class boost::serialization::access;
template <typename Ar>
void serialize(Ar& ar, unsigned)
{
ar & msg_type;
ar & msg_name;
ar & message_data;
}
} msg_struct;
namespace ipc = boost::interprocess;
int main() {
ipc::message_queue queue(ipc::open_or_create, "myqueue", 100, 4*1024);
msg_struct outgoing { 1, "outgoing.msg_name", msg_struct::mess1_t {
42,
"outgoing.struct_type.mess1.ReportedTime",
"outgoing.struct_type.mess1.ReceivedAt",
123,
234 }
};
std::ostringstream oss;
boost::archive::binary_oarchive oa(oss);
oa << outgoing;
assert(oss.str().size() <= queue.get_max_msg_size());
queue.send(&outgoing, sizeof(outgoing), 1);
}
Related
I have those two classes and I'm trying to deserialize them using boost
class WorldItem
{
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar &foreground;
ar &background;
ar &breakLevel;
ar &breakTime;
ar &water;
ar &fire;
ar &glue;
ar &red;
ar &green;
ar &blue;
}
public:
int foreground = 0;
int background = 0;
int breakLevel = 0;
long long int breakTime = 0;
bool water = false;
bool fire = false;
bool glue = false;
bool red = false;
bool green = false;
bool blue = false;
};
class Worlds
{
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar &width;
ar &height;
ar &name;
for (int i = 0; i < 100 * 60; i++)
{
ar &items[i];
}
ar &owner;
ar &weather;
ar &isPublic;
ar &isNuked;
}
public:
int width;
int height;
string name;
WorldItem *items;
string owner = "";
int weather = 0;
bool isPublic = false;
bool isNuked = false;
};
Here I'm creating a world in this way
Worlds generateWorld(string name, int width, int height)
{
Worlds world;
world.name = name;
world.width = width;
world.height = height;
world.items = new WorldItem[100 * 60];
}
and here im using this function to serialize the world
std::stringstream serialize_world(Worlds world)
{
std::stringstream str;
{
boost::archive::binary_oarchive oa(str);
oa << world;
}
return str;
}
So the serialize_world function is working without issues and i am inserting it value to mysql longblob.
But now when I'm trying to get the blob from MySql and deserialize it back by using this function
Worlds deserialize(std::string world)
{
Worlds wld;
std::istream *blobdata = WORLD_DATA(world);
{
boost::archive::binary_iarchive ia(*blobdata);
ia >> wld;
}
return wld;
}
I'm getting a Segmentation fault (core dumped) I don't know what's wrong.
Thanks.
Looks like you never return a value from generateWorld.
My compiler warns about this. Try enabling your compiler's diagnostics. I usually have -Wall -Wextra -pedantic enabled
Also in deserialize you never initialize items to anything. That is going to lead to UB.
This, too, could be diagnosed by most compilers (-fsanitize=address,undefined helps, although it makes compilation and runtime slow). There's also external tools like Valgrind that do these
Finally, I have no idea what is going on with blobdata, so I'm going to ignore that, but it too looks wrong.
Don't use raw new/delete
See also e.g. https://www.quora.com/Why-are-the-%E2%80%98new%E2%80%99-and-%E2%80%98delete%E2%80%99-keywords-considered-bad-in-modern-C++
Just use std::array then and be happy:
Live On Coliru
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/array.hpp>
#include <array>
#include <iostream>
#include <sstream>
class WorldItem {
private:
friend class boost::serialization::access;
template <class Ar> void serialize(Ar& ar, unsigned) {
ar& foreground& background& breakLevel& breakTime& water& fire& glue&
red& green& blue;
}
public:
int foreground = 0;
int background = 0;
int breakLevel = 0;
long long int breakTime = 0;
bool water = false;
bool fire = false;
bool glue = false;
bool red = false;
bool green = false;
bool blue = false;
auto operator<=>(WorldItem const&) const = default;
};
class Worlds
{
private:
friend class boost::serialization::access;
template <class Ar> void serialize(Ar& ar, unsigned) {
ar& width& height& name& items& owner& weather& isPublic& isNuked;
}
public:
int width;
int height;
std::string name;
std::array<WorldItem, 100 * 60> items;
std::string owner = "";
int weather = 0;
bool isPublic = false;
bool isNuked = false;
auto operator<=>(Worlds const&) const = default;
};
//So here im creating a world in this way
Worlds generateWorld(std::string name, int width, int height) {
Worlds world;
world.name = name;
world.width = width;
world.height = height;
return world;
}
std::string serialize_world(Worlds const& world) {
std::stringstream str;
{
boost::archive::binary_oarchive oa(str);
oa << world;
}
return str.str();
}
Worlds deserialize(std::string world) {
Worlds wld;
std::istringstream blobdata(world);
{
boost::archive::binary_iarchive ia(blobdata);
ia >> wld;
}
return wld;
}
int main() {
Worlds w = generateWorld("test", 6, 6);
Worlds clone = deserialize(serialize_world(w));
std::cout << "Worlds equal? " << std::boolalpha << (w == clone) << "\n";
}
Prints
Worlds equal? true
I have this map
std::map<IPv4Address,std::vector<Agent>> report;
Where agent is defined as the following
typedef struct
{
IPv4Address Address;
AgentType Type;
std::map <IPv4Address, IPRoute> RoutingTable;
MetricType metric;
int UpdateReceived = 0;
}Agent;
I am sending this Agent struct through tcp sockets and saving the values in the report std::map
int receive = recv(as.socket, (void *) &agent, sizeof(agent),0);
The routing table is initially empty. When the routing table size becomes >=1 the app crashes when adding to the map as seen below:
mutex.lock();
PrintInfo("Mutex locked");
if(report.find(as.ip) != report.end())
{
//f tells us if the agent was connected before to the router
bool f = false;
std::vector<Agent> tmpv =report[as.ip];
int tmp;
PrintInfo("Vector loop");
for(std::size_t i=0 ; i < tmpv.size() ; i++)
{
if(tmpv[i].Type == agent.Type)
{
f = true;
tmp = i;
break;
}
}
PrintInfo("Vector loop End");
if(f)
{
PrintInfo("Found -> Replacing");
--> This line crashes report[as.ip][tmp] = agent;
}
else
{
PrintInfo("Not Found -> Adding");
report[as.ip].push_back(agent);
}
PrintInfo("After add");
}
After serializing the struct using boost library everything worked fine.
Here is an example of serialization :
Struct :
typedef struct
{
template<class Archive>
void serialize(Archive &ar,const unsigned int version)
{
ar & Address & Type & InterceptionDuration & RoutingTable & metric & UpdateReceived;
}
IPv4Address Address;
AgentType Type;
double InterceptionDuration;
std::map <IPv4Address, IPRoute> RoutingTable;
MetricType metric;
int UpdateReceived = 0;
}Agent;
Serializing :
std::string SerializeAgent(Agent a)
{
std::ostringstream archive_stream;
boost::archive::text_oarchive archive(archive_stream);
archive << a;
std::string s = archive_stream.str();
return s;
}
Deserializing :
Agent DeserializeAgent(std::string s)
{
Agent a;
std::string r(&s[0],s.size());
std::istringstream archive_stream(r);
boost::archive::text_iarchive archive(archive_stream);
archive >> a;
return a;
}
Sending through socket :
std::string s = SerializeAgent(agent);
send(reporterSendingSocket,s.c_str(),s.size(),0);
Receiving through socket :
std::vector<char> response(REPORT_MAX_BUFFER_SIZE);
int receive = recv(as.socket, (void *) &response[0], response.size(),0);
I'm trying to serialize a minHeap object which contains a vector and an integer using Boost.
struct minHeap {
std::vector<keyNode> heapStructure; // A vector of many keyNodes
int size; // Current size of vector
minHeap() {
size = 0;
}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned version)
{
ar & heapStructure;
ar & size;
}
};
Now the heapStructure is a vector of keyNode and each keyNode contains a character, integer and two pointers of the object keyNode itself.
struct keyNode {
char data; // The character itself
int frequency; // Occurances of the character in the data stream.
keyNode * leftNode, *rightNode; // Left and right children of the root node (the keyNode itself)
keyNode() {
data = NULL;
frequency = 0;
leftNode = NULL;
rightNode = NULL;
}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned version)
{
ar &data;
ar &frequency;
ar &leftNode;
ar &rightNode;
}
};
The below (sample) code shows how I'm serializing and deserializing the file.
// Write Encoded Stream to File
ofstream outFile;
string outPath = filePath + ".enc";
outFile.open(outPath, ios::out | ios::binary); // TODO: Fix the output path
bitsetR bitStorage(outputStream);
boost::archive::binary_oarchive output(outFile);
output << bitStorage;
output << hTree;
outFile.close();
ifstream inFile;
inFile.open("demo.txt.enc"); // TODO: Fix the output path
bitsetR bitStr("");
boost::archive::binary_iarchive input(inFile);
minHeap temp;
input >> bitStr;
input >> temp;
I don't get any errors while serializing but deserializing fails with the following error (VS 2017):
Exception Thrown: Input Stream Error (boost::archive::archive_exception)
I should note here that the bitsetR object deserializes successfully. The exception is thrown when deserializing the minHeap object.
I think all that's needed is proper flush and close of the archive and stream in the correct order. This code works ok:
Live On Coliru
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/vector.hpp>
struct keyNode {
char data = 0; // The character itself
int frequency = 0; // Occurances of the character in the data stream.
keyNode *leftNode = nullptr;
keyNode *rightNode = nullptr; // Left and right children of the root node (the keyNode itself)
private:
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, unsigned) {
ar &data;
ar &frequency;
ar &leftNode;
ar &rightNode;
}
};
struct minHeap {
std::vector<keyNode> heapStructure; // A vector of many keyNodes
size_t size() const { return heapStructure.size(); }
private:
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, unsigned) {
ar &heapStructure;
}
};
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <fstream>
int main() {
minHeap hTree;
{
std::ofstream outFile("demo.txt.enc", std::ios::binary);
{
boost::archive::binary_oarchive output(outFile);
output << hTree;
}
}
{
std::ifstream inFile("demo.txt.enc");
boost::archive::binary_iarchive input(inFile);
minHeap temp;
input >> temp;
}
}
Note I can make it fail with a similar message by dropping the scopes:
int main() {
minHeap hTree;
std::ofstream outFile("demo.txt.enc", std::ios::binary);
boost::archive::binary_oarchive output(outFile);
output << hTree;
std::ifstream inFile("demo.txt.enc");
boost::archive::binary_iarchive input(inFile);
minHeap temp;
input >> temp;
}
Prints Live On Coliru
terminate called after throwing an instance of 'boost::archive::archive_exception'
what(): input stream error
bash: line 7: 16838 Aborted (core dumped) ./a.out
I'm creating a class that stores lots of doubles for saving/loading with boost. The load needs to be as fast as possible, so getting the binary format to work is the goal.
Basically, I have a class that stores a vector of structs:
vector<DataChunk>
where DataChunk stores a double array of fixed length
double data[2048]
When I test the functionality with using a text archive (text_iarchive), everything works great. However, when using the binary archive, I get memory access violation on deserializing the class.
More bizarrely, if I fill the double array with the same double value (i.e all elements of data[2048] are equal to 12345), it works. Varying double values seems to crash it, though (see below).
Here's my RawData class:
#pragma once
#include <boost\serialization\vector.hpp>
#include <boost\serialization\array.hpp>
using namespace std;
struct DataChunk
{
public:
double data[2048]; //THIS IS THE PROBLEM AREA
int end;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & data;
ar & end;
}
};
class RawData
{
private:
vector<DataChunk> chunks;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & chunks;
}
public:
void add_chunk(DataChunk chunk){chunks.push_back(chunk);};
vector<DataChunk> get_chunks(){return chunks;};
static void save(RawData rd, string path);
static bool load(RawData & rd, string path);
void add_raw_data(vector<double> raw_data);
vector<double> combine_chunks();
};
My save and load functions look like this:
void RawData::save(RawData rd, string path)
{
std::ofstream file(path);
if(file.good())
{
boost::archive::binary_oarchive oa(file, std::ios::binary);
//boost::archive::text_oarchive oa(file);
oa << rd;
}
file.flush();
file.close();
}
bool RawData::load(RawData & rd, string path)
{
std::ifstream file(path);
if(file.good())
{
boost::archive::binary_iarchive ia(file, std::ios::binary);
//boost::archive::text_iarchive ia(file);
ia >> rd;
file.close();
return true;
}
else
return false;
}
In my main function, I test it like this:
string path = "test.data";
RawData old_data;
vector<double> raw_data;
for(int i = 0; i < 5000; i++)
raw_data.push_back(i * 2048); //change this to constant value and it works...
old_data.add_raw_data(raw_data);
//serialize
RawData::save(old_data, path);
//deserialize
RawData new_data;
RawData::load(new_data, path);
//grab the chunks and test the values
vector<DataChunk> chunks_in = new_data.get_chunks();
for(int i = 0; i < chunks_in.size(); i++)
for(int j = 0; j < chunks_in[i].end; j++)
cout<<chunks_in[i].data[j]<<", ";
return 0;
You will want to use
template <class Archive> void serialize(Archive &ar, unsigned) {
ar & end;
ar & boost::serialization::make_array(data, end);
}
See http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/wrappers.html#arrays
Here is the demo, selfcontained:
Live On Coliru
#include <boost/serialization/vector.hpp>
#include <boost/serialization/array.hpp>
struct DataChunk {
public:
double data[2048]; // THIS IS THE PROBLEM AREA
int end;
private:
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, unsigned) {
ar & end;
ar & boost::serialization::make_array(data, end);
}
};
#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
class RawData {
private:
std::vector<DataChunk> chunks;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, unsigned) { ar &chunks; }
public:
void add_chunk(DataChunk chunk) { chunks.push_back(chunk); };
std::vector<DataChunk> get_chunks() { return chunks; };
static void save(RawData rd, std::string path);
static bool load(RawData &rd, std::string path);
void add_raw_data(std::vector<double> raw_data) {
DataChunk chunk;
auto const csize = boost::size(chunk.data);
size_t n = raw_data.size(),
offs = 0ul;
while (n>0) {
auto n_ = std::min(n, csize);
std::copy_n(raw_data.begin() + offs, n_, chunk.data);
chunk.end = n_;
chunks.push_back(chunk);
offs += n_;
n -= n_;
}
}
std::vector<double> combine_chunks() {
std::vector<double> r;
boost::for_each(chunks, [&r](DataChunk const& c) {std::copy_n(c.data, c.end, back_inserter(r));});
return r;
}
};
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <fstream>
void RawData::save(RawData rd, std::string path) {
std::ofstream file(path);
if (file.good()) {
boost::archive::binary_oarchive oa(file, std::ios::binary);
// boost::archive::text_oarchive oa(file);
oa << rd;
}
file.flush();
file.close();
}
bool RawData::load(RawData &rd, std::string path) {
std::ifstream file(path);
if (file.good()) {
boost::archive::binary_iarchive ia(file, std::ios::binary);
// boost::archive::text_iarchive ia(file);
ia >> rd;
file.close();
return true;
} else
return false;
}
#include <iostream>
RawData generate() {
RawData data;
std::vector<double> raw_data;
for (int i = 0; i < 5000; i++)
raw_data.push_back(i * 2048);
data.add_raw_data(raw_data);
return data;
}
int main() {
std::string const path = "test.data";
{
// serialize
RawData const old_data = generate();
RawData::save(old_data, path);
}
{
// deserialize
RawData new_data;
RawData::load(new_data, path);
// grab the chunks and test the values
for (auto d : new_data.combine_chunks())
std::cout << d << ", ";
}
}
I'm trying to make a serialization of an object and then to deserialize it. Even though it seems that everything I wrote is ok I'm still getting an error during the deserialization.
int main(){
MapAttributes mapAtt(MAP_SIZE,MAP_SIZE);
initMapFromImage("map1.png",&mapAtt);
int prevxMax = mapAtt.prevxMax ;
int prevyMax = mapAtt.prevyMax ;
int prevxMin = mapAtt.prevxMin ;
int prevyMin = mapAtt.prevyMin ;
PixelCoords pose = PixelCoords(mapAtt.robotPose.dx, mapAtt.robotPose.dy);
PixelCoords target = PixelCoords( 2048+250, 2048+250 );
PartitionGraphNodes partitionGraph(&mapAtt);
PartitionGraphNodes partitionGraph2(&mapAtt);
partitionGraph.createIncrementalPartition(pose,target);
if (partitionGraph.nodes.size()!=0){
saveSerializedObject<PartitionGraphNodes(partitionGraph,"partition_graph_marshall");
std::cout << "size= " << partitionGraph.nodes.size() << "\n";
restoreSerializedObject<PartitionGraphNodes>(partitionGraph2,"partition_graph_marshall");
}
else{
std::cout << "RUN FOR YOUR LIVES!!!\n";
}
return 0;
This is my code where I'm trying to get my objects serialized and deserialized.
Here is the function for the serialization and the deserialization:
template<class T>
void saveSerializedObject(const T &s, const char * filename){
// make an archive
std::ofstream ofs(filename);
boost::archive::text_oarchive oa(ofs);
oa << s;
}
template<class T>
void restoreSerializedObject(T &s, const char * filename)
{
// open the archive
std::ifstream ifs(filename);
if (ifs.good()) {
std::cout << "Coming!!!\n";
boost::archive::text_iarchive ia(ifs);
ia >> s;
} else {
// throw an error or something
assert(false);
}
}
Finally I have wrote the code for the serialization exactly as the Boost documentation suggests, but I still get an error: an instance of 'boost::archive::archive_exception' what(): input stream error. Can you help me with that?
EDIT:
As it is clear enough, initially I'm trying to serialize an object of class PartitionGraphNodes. So this is how an PartitionGraphNodes object is serialized:
#include <boost/serialization/base_object.hpp>
class PartitionGraphNodes: public NodesVector{
private:
std::vector<int> targetNeighbors; //!<Vector holding target neighbors
std::vector<int> robotNeighbors; //!<Vector holding robot neighbors
std::vector<PixelCoords> uniformPartition;
public:
PartitionGraphNodes(MapAttributes* mapAttr);
void createIncrementalPartition(PixelCoords startPos, PixelCoords target);
int insertNodeInPartition(Node currNode);
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
// serialize base class information
std::cout << "In partition_serial" << "\n";
ar & boost::serialization::base_object<NodesVector>(*this);
}
};
#include <boost/serialization/vector.hpp>
class NodesVector{
protected:
//~ std::vector<Voronode> nodes;
public:
NodesVector(void){};
std::vector<Node> nodes;
MapAttributes* mapAttributes;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
std::cout << "In nodesVector_serial" << "\n";
ar & nodes;
}
};
#include <boost/serialization/vector.hpp>
class Node{
public:
PixelCoords p; //!< The coordinates of the node
bool visited; //!< True if the node has been visited
unsigned int ID; //!< The node's ID
int parent;
std::vector<PixelCoords> neigh; //!< Vector of the neighbors of the node (coords)
std::vector<unsigned int> neighID; //!< Vector of the neighbors' IDs
std::vector<float> dist; //!< Vector of the distances of the neighbors
Weight w; //!< The node's weight
std::vector<PixelCoords> path;
Node(PixelCoords a) {p=a;}
Node(PixelCoords a,unsigned int IDt) {p=a; ID=IDt;}
Node(void){}
void makeNeighbor(Node &a);
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
std::cout << "In nodes_serial" << "\n";
ar & p;
ar & visited;
ar & ID;
ar & parent;
ar & neigh;
ar & neighID;
ar & dist;
ar & w;
}
};
#endif
I think you need
BOOST_CLASS_EXPORT();
lines.
See for instance the answers to this question: Where to put BOOST_CLASS_EXPORT for boost::serialization?