RPC.06-序列化-ProtoBuf

ProtoBuf(Protocol Buffers )是Google的开源的序列化 & 反序列化工具 https://developers.google.com/protocol-buffers/

ProtoBuf C++使用

使用步骤:

  • 定义proto文件,文件的内容就是定义我们需要存储或者传输的数据结构,也就是定义我们自己的数据存储或者传输的协议。
  • 安装protocol buffer编译器来编译自定义的.proto文件,用于生成.pb.h文件(proto文件中自定义类的头文件)和 .pb.cc(proto文件中自定义类的实现文件)。
  • 使用protocol buffer的C++ API来读写消息

protocol buffer 生成的函数, 除了getter和setter之外, 还有:

标准消息函数(Standard Message Methods)
每一个消息(message)还包含了其他一系列函数,用来检查或管理整个消息,包括:

bool IsInitialized() const; //检查是否全部的required字段都被置(set)了值。

void CopyFrom(const Person& from); //用外部消息的值,覆写调用者消息内部的值。

void Clear(); //将所有项复位到空状态(empty state)。

int ByteSize() const; //消息字节大小

Debug的API, 包括:

string DebugString() const; //将消息内容以可读的方式输出

string ShortDebugString() const; //功能类似于,DebugString(),输出时会有较少的空白

string Utf8DebugString() const; //Like DebugString(), but do not escape UTF-8 byte sequences.

void PrintDebugString() const; //Convenience function useful in GDB. Prints DebugString() to stdout.

解析&序列化(Parsing and Serialization)函数, 包括:

bool SerializeToString(string* output) const; //将消息序列化并储存在指定的string中。注意里面的内容是二进制的,而不是文本;我们只是使用string作为一个很方便的容器。

bool ParseFromString(const string& data); //从给定的string解析消息。

bool SerializeToArray(void * data, int size) const //将消息序列化至数组

bool ParseFromArray(const void * data, int size) //从数组解析消息

bool SerializeToOstream(ostream* output) const; //将消息写入到给定的C++ ostream中。

bool ParseFromIstream(istream* input); //从给定的C++ istream解析消息。

使用示例:

//test.cpp

#include <iostream>
#include <string>
#include "student.pb.h"
using namespace std;

int main(int argc, char* argv[]){
GOOGLE_PROTOBUF_VERIFY_VERSION;

// 创建message实例, 并设置属性:
tutorial::Student student;
student.set_id(201421031059);
student.set_email("dablelv@tencent.com");
// 增加 repeated属性
tutorial::Student::PhoneNumber* phone_number1 = student.add_phone();
phone_number1->set_number("13811112222");
tutorial::Student::PhoneNumber* phone_number2 = student.add_phone();
phone_number2->set_number("010-1112222");


// 序列化:
string serializedStr;
student.SerializeToString(&serializedStr);
cout<<"serialization result:"<<serializedStr<<endl;
cout<<endl<<"debugString:"<<student.DebugString();


// 反序列化:
tutorial::Student deserializedStudent;
if(!deserializedStudent.ParseFromString(serializedStr)){
cerr << "Failed to parse student." << endl;
return -1;
}
cout<<"deserializedStudent debugString:"<<deserializedStudent.DebugString();
cout <<endl<<"Student ID: " << deserializedStudent.id() << endl;
// 判断有无属性
if (deserializedStudent.has_email()){
cout << "E-mail address: " << deserializedStudent.email() << endl;
}
// 对 repeated属性进行遍历
for (int j = 0; j < deserializedStudent.phone_size(); j++){
const tutorial::Student::PhoneNumber& phone_number = deserializedStudent.phone(j);
cout <<phone_number.number()<<endl;
}

google::protobuf::ShutdownProtobufLibrary();
}

@ref: Protocol Buffers C++入门教程 - 云+社区 - 腾讯云

varint

@ref: Protobuf 终极教程 @todo