Serializing C++ objects - c++

I would like to implement a Serialization Class which takes in an object and converts it into a binary stream and stored in a file. Later, the object should be reconstructed from a file.
Though this functionality is provided by BinaryFormatter in C#, I would like to design my
own Serialization class from scratch.
Can someone point to some resources ?
Thanks in advance

I would like to give you a negative answer. It is less useful but it still may be.
I have been using boost serialization for several years and it was one of the greatest strategic mistakes of my company. It produces very large output, it is very slow, it propagates a whole bunch of dependencies making everything impossibly slow to compile, and then it is hard to get out because you have existing serialized formats. Further, it behaves differently on different compilers, thus upgrade from VS2005 to 2010 actually caused us to write a compatibility layer, which is also hard coz the code is very hard to understand.

Here are 2 solutions for C++ serialization:
Stephan Beal's s11n serialization library
boost serialization library
I personally only have experience with the 1st one and actually only used text based serializers, but i know that it's easy to define binary serializers for use with s11n.

I have been using boost::serialization library for a while now and I think it is very good. You just need to create the serialization code like this:
class X {
private:
std::string value_;
public:
template void serialize(Archive &ar, const unsigned int version) {
ar & value_;
};
}
No need to create the de-serialization code ( that's why they used the & operator ). But if you prefer you can still use the << and >> operators.
Also it's possible to write the serialization method for a class with no modification ( ex.: if you need to serialize an object that comes from a library ). In this case, you should do something like:
namespace boost { namespace serialization {
template
void serialize(Archive &ar, X &x const unsigned int version) {
ar & x.getValue();
};
}}

The C++ Middleware Writer may be of interest. It has performance advantages over the serialization library in Boost. It also automates the creation of serialization functions.

Related

Using boost serialization to convert class object to vector<unsigned char>

I am referring this : https://theboostcpplibraries.com/boost.serialization-class-hierarchies
I want to serialize object of my class, to std::vector<unsigned char>
class Person {
int id;
std::string name;
}
And then deserialize back to that class.
But I do not completely understand the implementation in the above URL. Can anybody help?
In such case it is best to see original documentation.
Blogs are often written by people who are in learning stage so in most cases they are not trustworthy (I don't say this is the case, but you should have limited trust to blogs written by someone you do not known).
The whole trick here is template method void serialize(Archive & ar, const unsigned int version).
Since it is a template once it is used to serialize and once to deserialize data.
Since code is doing writing and reading at the same time, stream operators << >> can't be used. Authors of library decided to use bit wise and operator & to express that it can do a reading and writing.
It looks strange like definition of a reference, but note on left side you have argument of method and or right side you have a field name.

Generate operator== using Boost Serialization?

Problem: I have a set of classes for which I have already implemented boost serialization methods. Now, I want to add an operator== to one class that contains many of the other classes as its members. This comparison should be straightforward: A deep, member wise comparison.
Idea: Since the existing serialization methods already tell the compiler everything it needs to know, I wonder if this can be used to generate efficient comparison operators.
Approach 1: The simplest thing would be to compare strings containing serializations of the objects to be compared. The runtime of this approach is probably much slower than handcrafted operator== implementations.
Approach 2: Implement a specialized boost serialization archive for comparisons. However, implementing this is much more complicated and time consuming than implementing either handcrafted operators or approach 1.
I did a similar thing recently for hashing of serializable types:
Hash an arbitrary precision value (boost::multiprecision::cpp_int)
Here I "abused" boost serialization to get a hash function for any Boost Multi Precision number type (that has a serializable backend).
The approach given in the linked answer is strictly more lightweight and much easier to implement than writing a custom archive type. Instead, I wrote a custom custom Boost Iostreams sink to digest the raw data.
namespace io = boost::iostreams;
struct hash_sink {
hash_sink(size_t& seed_ref) : _ptr(&seed_ref) {}
typedef char char_type;
typedef io::sink_tag category;
std::streamsize write(const char* s, std::streamsize n) {
boost::hash_combine(*_ptr, boost::hash_range(s, s+n));
return n;
}
private:
size_t* _ptr;
};
This is highly efficient because it doesn't store the archive anywhere in the process. (So it sidesteps the dreadful inefficiency of Approach 1)
Applying to Equality Comparison
Sadly, you can't easily equality compare in streaming mode (unless you can be sure that both streams can be consumed in tandem, which is a bit of finicky assumption).
Instead you would probably use something like boost::iostreams::device::array_sink or boost::iostreams::device::back_insert_device to receive the raw data.
If memory usage is a concern you might want to compress it in memory (Boost Iostreams comes with the required filters for zip/bzip too). But I guess this is not your worry - as you would likely not be trying to avoid duplicating code in that case. You could just implement the comparison directly.

boost serialization of pointer to primitive without wrapper

Is there any way to serialize a pointer to a primitive without wrapping it in a class?
I notice a comment on the following question that it would require tracking all primitives of that type in the program, which I guess could slow down serialization somewhat. But what if I'm ok with that? Is there a way to enable tracking for all primitive types?
How do I serialize a class containing pointers to primitives?
I found this thread (from 2006) which also alludes to the problem. It seems that serializing a pointer to primitive should be possible, but the lack of tracking makes it something that you probably would not want. It seems to allude to the possibility but does not explain if it was ever implemented.
http://boost.2283326.n4.nabble.com/serialization-serialization-of-pointers-to-primitive-types-td2561086.html
you can write a overload function for operator&,like this:
template<class Archive>
void operator&(Archive & ar, const char* &p)
{
}

boost serialization omit version for a wrapper

How can I tell boost that for a particular structure it should not write/read a class "version" identifier?
I am writing some wrapper classes for serializing some types in a smaller fashion (like a variable length integer). If the wrapper gets a class version written the whole point of the size reduction is lost (it'll end up bigger in most cases).
For example, given integer a I'll be replacing this code:
ar & a;
with this:
ar & wrapper(a);
I see the is_wrapper trait, but I can't really find any docs on what that does, or if it might help.
Add
BOOST_CLASS_IMPLEMENTATION(wrapper, boost::serialization::object_serializable)
It's the documented way.

Can I tell Boost.MPI which class version to use with Boost.Serialization?

I'm using Boost.MPI to exchange messages between processes. Each message carries one of my classes, serialized using Boost.Serialization. I also use the same serialization code to save that class to a file. What I need to send over MPI is smaller than what I need to save to a file (fewer relevant members). I was thinking that it would be nice to use the class versioning, supported by the Serialization library, to tell Boost.MPI to send the non-default version of the class, but I can't seem to find a way to do so. Do you know if this is possible?
It is not possible to serialize two different versions of the same type in the same binary module. The reason is that the version used is a compile time constant specified using the BOOST_CLASS_VERSION construct (the version number defaults to zero if not specified).
What you could try is to implement specializations of the serialization member function for your type for specific archive types:
// generic overload, used for everything except the MPI archives
template <class Archive>
void serialize(Archive & ar, const unsigned int version)
{
// do 'normal' (file-based) serialization
}
// overload for MPI archive used while deserialization
void serialize(boost::mpi::packed_iarchive& ar, const unsigned int version)
{
// do MPI deserialization
}
// overload for MPI archive used while serialization
void serialize(boost::mpi::packed_oarchive& ar, const unsigned int version)
{
// do MPI serialization
}
Similarily, you could provide overloads when using the split load/save serialization functions.