一. 简介
Protocol Buffers 是一种数据序列化的格式。特点是语言无关
,平台无关
。
相比于 XML 的优势是更小
,更快
和更简单
。适合数据存储
或 RPC
数据交换,可用于通信协议
。
支持的语言包括:C++,C#,Dart,Go,Java,Python 等。
二. 安装
2.1. cmake
命令行安装:
$ sudo apt install cmake
源码安装:https://cmake.org/download/
$ tar xf cmake-3.13.3.tar.gz
$ ./configure
$ make
$ sudo make install
2.2. protobuf
https://github.com/protocolbuffers/protobuf/releases
因为这篇是 cmake
和 protobuf
的结合使用,所以我这里安装的是 protobuf-cpp-3.6.1.tar.gz
$ tar xf protobuf-cpp-3.6.1.tar.gz
$ cd protobuf-3.6.1
$ ./configure
$ make
$ sudo make install
三. 例子
我们定义个类 Person,包含 pb 的结构 Book:
person.h 如下:
class Person {
public:
Person() {}
~Person() {}
void SetPerson(const std::string &name, int age);
void SetBook(const std::string &bookName, float price);
void Print();
private:
std::string name_;
int age_;
test::Book book_;
};
person.cpp 如下:
void Person::SetPerson(const std::string &name, int age) {
name_ = name;
age_ = age;
}
void Person::SetBook(const std::string &bookName, float price) {
book_.set_name(bookName);
book_.set_price(price);
}
void Person::Print() {
std::cout << name_
<< " is " << age_ << " years old. \n";
std::cout << "His favorite book is " << book_.name()
<< ", and it costs " << book_.price() << "¥.\n";
}
proto 格式定义如下:
syntax = "proto3";
package test;
message Book {
string name = 1;
float price = 2;
}
注意: 这个是 proto3 的,proto2 的类型前面有 required 或 optional 等字样。
接下来我们编写 cmake 来自动产生 proto 对应的 .cc 和 .h 文件,文件名分别是 test.pb.cc
和 test.pb.h
。
# 查找 protobuf
find_package(Protobuf REQUIRED)
if (PROTOBUF_FOUND)
message("protobuf found")
else ()
message(FATAL_ERROR "Cannot find Protobuf")
endif ()
# 编译 proto 为 .cpp 和 .h
set(PROTO_FILES proto/test.proto)
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${PROTO_FILES})
message("PROTO_SRCS = ${PROTO_SRCS}")
message("PROTO_HDRS = ${PROTO_HDRS}")
# 关联 protobuf 到最后的二进制文件
add_executable(cmake_protobuf
src/person.cpp
src/main.cpp
${PROTO_SRCS}
${PROTO_HDRS})
target_include_directories(${PROJECT_NAME}
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
PUBLIC ${PROTOBUF_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${PROTOBUF_LIBRARIES})
注: 上面是 cmake 根据 proto 自动产生对应文件,你也可以在 proto 目录下手动执行 protoc test.proto --cpp_out=. 来产生。
main.cpp 如下:
int main() {
Person p;
p.SetPerson("Alan", 18);
p.SetBook("Effective C++", 51.8);
p.Print();
return 0;
}
完整的例子见 https://github.com/alandtsang/cppdemo/tree/master/src/cmake-protobuf
参考
https://developers.google.com/protocol-buffers/docs/cpptutorial