protobuf是什么?
简单地说,就是谷歌开发的一种跨平台,跨语言,可拓展的序列化,反序列化工具【功能类似json,xml,多用于文本传输】
protobuf优点
主要是更加轻便,编码后的数据比xml和json都要小
protobuf使用流程
- 配置环境
- 将需要传递的数据写成.proto描述文件
- 使用生成工具【protoc.exe】生成需要的特定语言的类型定义文件【例如C++就生成.c、.h,Js就生成.js】
- 使用protobuf接口初始化自定义类型对象
- 编码
- 传输
- 解码成自定义对象
准备文件
- 下载protobuf源码存放到:protobuf仓库
- 下载并配置cmake
2.1. cmake下载地址
2.2. 确保控制台识别“cmake”命令,否则可能没有把cmake.exe所在目录加入系统环境变量 - 查看protobuf的ReadMe继续配置:
3.1. 下载googletest仓库
3.2. 将googletest-master中的googletest目录重命名为gtest并剪贴到googlemock目录
3.3. 将googletest-master中的googlemock目录重命名为gmock并剪贴到protobuf-master目录 - 打开cmake-gui.exe,点击BrowseSource,选择protobuf–master中的cmake目录
- 点击browsebuild选择项目生成目录【我这里姑且命名为Install】
- 然后,Configure,Generate,注意这里生成的时候需要选定发布平台是32位还是64位,后面不能改
- 生成成功后打开生成的protobuf.sln
- 分别对图中三个项目点击生成
libprotobuf libprotoc 生成运行时需要的两个静态库
protoc 生成【能够根据proto文件生成对应语言数据结构定义的】代码生成器【exe】
到这里已经具备所有文件,可以应用到项目中去了。
【举个例子】如何配置protobuf到具体项目
- 新建windows控制台空项目
【个人习惯】 略作整理目录结构
—LearnProtobuf
------3rd
---------protobuf
------proj.win32
---------LearnProtobuf.sln
---------protobuf
---------proto - 置入文件
2.1 将protobuf-master/src目录里的内容全部拷贝到3rd/protobuf目录
2.2 将两个lib文件放到proj.win32/protobuf目录下
2.3 将protoc.exe放到proj.win32/proto目录下 - 设置项目属性
3.1 将3rd/protobuf目录加入附加包含目录
3.2 设置SDL检查为 “否”
3.3 代码生成设置成多线程调试MTd
3.4 将proj.win32/protobuf目录加入到附加库目录
3.5 在 “连接器-命令行” 添加两个静态库名 - 书写.proto文件
enum Type{
First = 1;
Second = 2;
}
message Message{
required sint32 id = 1;
required Type type = 3;
repeated bool bool_array = 2;
}
message HugeMessage{
required Message msg = 1;
}
message Person{
required string name = 1;
optional string email = 3;
}
- 生成类型定义文件,并将生成的文件添加到工程
- 测试代码及运行结果
#include<cstdlib>
#include<iostream>
using namespace std;
#include "proto/message.pb.h"
int main(int argc, char* argv)
{
auto p = new Person();
//赋初始值
p->set_name("zerlenzhang");
p->set_email("[email protected]");
cout << "初始值:\t" << p->name() << " " << p->email() << endl;
//编码
string data;
data = p->SerializeAsString();
//传输
//解码
Person another;
another.ParseFromString(data);
cout << "最终值:\t" << another.name() << " " << another.email() << endl;
delete p;
system("pause");
return 0;
}
如有问题,欢迎沟通