protobuf安装及其简单使用

大耗子 2020年06月22日 141次浏览

文章链接:https://codemouse.online/archives/2020-06-22163236

protocol buffers 是什么?

Protocol buffers 是一种语言中立,平台无关,可扩展的序列化数据的格式,可用于通信协议,数据存储等。

Protocol buffers 在序列化数据方面,它是灵活的,高效的。相比于 XML 来说,Protocol buffers 更加小巧,更加快速,更加简单

一旦定义了要处理的数据的数据结构之后,就可以利用 Protocol buffers 的代码生成工具生成相关的代码。甚至可以在无需重新部署程序的情况下更新数据结构。

只需使用 Protobuf 对数据结构进行一次描述,即可利用各种不同语言或从各种不同数据流中对你的结构化数据轻松读写。

Protocol buffers 很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

protobuf安装极其编译流程

安装工具->根据编写的proto文件产生c++代码
下载点击:protobuf-cpp-3.8.0.tar.gz
官方github发布版本链接:https://github.com/protocolbuffers/protobuf/releases

  1. 解压

tar zxvf protobuf-cpp-3.8.0.tar.gz

  1. 编译(make的时间有点长)
cd protobuf-3.8.0/
./configure 
make
sudo make install
  1. 显示版本信息

protoc –version

  1. 编写proto文件
    注意:目前 protocol buffers 最新版本是 proto3,与老的版本 proto2 还是有些区别的。这两个版本的 API 不完全兼容。
  2. 将proto文件生成对应的.cc和.h文件
    create.sh文件
#!/bin/sh
# proto文件在哪里
SRC_DIR=./
# .h .cc输出到哪里
DST_DIR=../

#C++
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/*.proto
  1. 编译范例
    比如:

g++ -o code_test code_test.cpp IM.BaseDefine.pb.cc IM.Login.pb.cc -lprotobuf -lpthread

proto文件的编写

范例代码下载->person.rar
option optimize_for = LITE_RUNTIME;

  • optimize_for是文件级别的选项,Protocol Buffer定义三种优化级别SPEED/CODE_SIZE/LITE_RUNTIME。缺省情况下是SPEED。

    1. SPEED: 表示生成的代码运行效率高,但是由此生成的代码编译后会占用更多的空间。

    2. CODE_SIZE: 和SPEED恰恰相反,代码运行效率较低,但是由此生成的代码编译后会占用更少的空间,通常用于资源有限的平台,如Mobile。

    3. LITE_RUNTIME: 生成的代码执行效率高,同时生成代码编译后的所占用的空间也是非常少。这是以牺牲Protocol Buffer提供的反射功能为代价的。因此我们在C++中链接Protocol Buffer库时仅需链接libprotobuf-lite,而非libprotobuf。在Java中仅需包含protobuf-java-2.4.1-lite.jar,而非protobuf-java-2.4.1.jar。

IM.Login.proto文件

syntax = "proto3";  // syntax 版本2/3是不一样,默认是proto2
package IM.Login;	//  package 生成对应的C++命名空间 IM::Login::
import "IM.BaseDefine.proto";	// import 引用其他proto文件
option optimize_for = LITE_RUNTIME; // 做效率与空间优化

// message关键字 代表一个对象
message Phone{
    string number = 1;	//等于的数字代表了位置
    IM.BaseDefine.PhoneType phone_type = 2; // 使用别的包的定义类型
}

message Book{
    string name = 1;
    float price = 2;
}

message Person{
    string  name    = 1;
    int32   age     = 2;
    repeated string languages = 3;
    Phone   phone   = 4;
    repeated Book   books   = 5;	// repeated相当于设置为数组,可以嵌套对象
    bool            vip     = 6;
    string          address = 7;
}

//使用T开头测试
message TInt32{
    int32   int1     = 1;
}

message TString{
    string   str1     = 1;
}

IM.BaseDefine.proto文件

syntax = "proto3";
package IM.BaseDefine;

option optimize_for = LITE_RUNTIME;

enum PhoneType{
	PHONE_DEFAULT			= 0x0;		
    PHONE_HOME              = 0x0001;   // 家庭电话
    PHONE_WORK              = 0x0002;   // 工作电话     
}