This post is meant as a brief introduction that will point you in the right direction rather than an exhaustive tutorial. Here we go…
Have you ever had to write code that serialized structured data into an efficient binary format, to be later saved to disk or sent over the network? Do you remember how difficult and time consuming it was? Haven’t you wished there was a standard C++ library to do it instead of reinventing the wheel? Well, today is your lucky day 🙂
Say hello to Google’s Protocol Buffers! It is a highly portable (and free!) library that allows you to define near arbitrary (numerical, strings, structures, lists, vectors, maps, you name it) data formats and easily serialize and deserialize them into a platform portable binary format. Why not use XML you may ask? How about 3 to 10 times smaller output, and 20 to 100 times faster serialization and deserialization just to name a few 🙂
Let’s start by defining a protocol buffer file that defines a “Person” data structure:
1 2 3 4 5 6 7 8 9 10 |
syntax = "proto2"; package data; message Person { required string name = 1; required int32 dob = 2; optional string email = 3; } |
Save that to protobuf.proto file and let’s compile it using the protoc code generator. Yes, Protocol Buffers is a code generator; it takes as input a .proto file and spits out C++ classes (it can also produce code in C#, Java, JS, ObjC, PHP, Python, and Ruby).
protoc -I=. –cpp_out=. protobuf.proto
protoc basic usage.
The above command will produce 2 files:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#include <iostream> #include <string> #include "protobuf.pb.h" using namespace std; int main(int argc, char** argv) { GOOGLE_PROTOBUF_VERIFY_VERSION; data::Person p; p.set_name("Martin Vorbrodt"); p.set_dob(19800830); string binary; p.SerializeToString(&binary); data::Person p2; p2.ParseFromString(binary); cout << "Name = " << p2.name() << endl; cout << "DOB = " << p2.dob() << endl; cout << "EMail = " << p2.email() << endl; google::protobuf::ShutdownProtobufLibrary(); return 1; } |
This code is pretty self explanatory. We create, set and serialize one data structure of type data::Person, then deserialize it into another. The output is what we would expect:
Name = Martin Vorbrodt
Program output.
DOB = 19800830
EMail = [email protected]
That’s enough of an introduction. I hope you will read up on Protocol Buffers and realize the enormous potential of this library. Happy coding!
P.S. As always, complete source and build files available at my GitHub.
bjson
is there a portable library for it?