protobuf比json更牛逼一点,prtobuf是直接生成二进制格式。占用的带宽比json少,因为序列化完的大小也比json小,不过学起来可能比json复杂些。
安装
安装protobuf,遇到了挺多问题,记录一下,
我下载的版本是3.11.0,我自己有自己的个人的小网站,推荐来我的网站来下载,毕竟速度会更快一些下载链接
傻瓜式一路安装的一路安装
1、解压压缩包:unzip protobuf-master.zip
2、进入解压后的文件夹:cd protobuf-master
3、安装所需工具:sudo yum install autoconf automake libtool curl make g++ unzip
4、自动生成configure配置文件:./autogen.sh
5、配置环境:./configure
6、编译源代码(时间比较长):make
7、安装:sudo make install
8、刷新动态库:sudo ldconfig
在第四步的时候,centos会出现这个警告,这个警告要处理的哦也推荐来我的小网站下载,在github下载是真的慢下载链接,需要下载googletest解压后放在./protobuf-3.6.1/third_party/googletest,把之前原有的googletest删掉就行,然后再次执行./autogen.sh之后的
参考的博客
看一下我当时下这小东西的时间,真小水管速度,1MB的东西下载了一年,哈哈哈
./configure如果最后有警告一定要处理!!!我没有处理选择忽视警告,导致我搞了一个上午才搞定protobuf的安装,再次提醒!
可以来我的个人小网站下载,上面上传了protobuf和googletest下载链接
安装完成!
C++使用protobuf
初识protobuf
touch test.proto #以.proto结尾的哦
vim test.proto
// 配置文件
syntax = "proto3"; // 声明了protobuf的版本
package fixbug; // 声明了代码所在的包,就是生成一个namespace作用域
// 定义传输类型,例如name pwd
message LoginRequest{
string name = 1;// 这个意思是第一个参数,不是1给他赋值
string pwd = 2;
}
// 定义登录响应消息类型
message LoginResponse{
int32 errcode = 1;
string errms = 2;
bool success = 3;
}
protoc test.proto --cpp_out=./
生成两个文件test.pb.cc test.pb.h,我们编码是要用到的。
#include <iostream>
#include "test.pb.h"
#include <string>
using namespace std;
using namespace fixbug; // 这就是当时的package
int main()
{
LoginRequest req;
req.set_name("zhang san");
req.set_pwd("123456");
std::string send_str;
// serialize序列化的意思,所以这是序列化从对象变成了string类型
if(req.SerializeToString(&send_str)){
std::cout << send_str << endl;
}
// 反序列化,就是把一个string转换成对象。
LoginRequest reqB;
if(reqB.ParseFromString(send_str)){
cout << reqB.name() << endl;
cout << reqB.pwd() << endl;
}
// cout << "hello world!" << endl;
return 0;
}
vim makefile #写个简单的Makefile
test_protobuf:main.cpp test.pb.cc
g++ $^ -o $@ -std=c++11 -lprotobuf
protobuf的列表属性
在message中加上repeated关键字就是一个列表属性
liebiao.proto文件
// 配置文件
syntax = "proto3"; // 声明了protobuf的版本
package fixbug; // 声明了代码所在的包,就是namespace
// 多份代码共用这一个
message ResultCode{
int32 errcode = 1;
string errms = 2;
}
// 定义传输类型,例如name pwd
message LoginRequest{
string name = 1;// 这个意思是第一个参数,不是给把1给他赋值
string pwd = 2;
}
message LoginResponse{
ResultCode result = 1;
bool success = 2;
}
message GetFriendListsRequest{
uint32 userid = 1;
}
message User{
bytes name = 1;
uint32 age = 2;
enum Sex{
MAN = 0;
WOMAN = 1;
}
Sex sex = 3;
}
message GetFriendListsResponse{
ResultCode result = 1;
repeated User friend_list = 2;// 定义了一个列表类型
}
#include <iostream>
#include <string>
#include "liebiao.pb.h"
using namespace std;
using namespace fixbug;
int main(){
/*
LoginResponse rsp;
ResultCode* rc = rsp.mutable_result();// mutable返回的是指针,直接result是const&
rc->set_errcode(1);
rc->set_errmsg("登录失败")
*/
GetFriendListsResponse rsp;
// rsp.result(); // 获取的是const&类型
ResultCode* rc = rsp.mutable_result();// 获取的就是指针类型
rc->set_errcode(0);
User* user1 = rsp.add_friend_list();
user1->set_name("zhangsan");
user1->set_age(20);
user1->set_sex(User::MAN);
User* user2 = rsp.add_friend_list();
cout << rsp.friend_list_size() << endl;
return 0;
}
总结一下protobuf的使用
-
解释一下message对应着啥东西
-
proto中的message对应就生成一个类,message中的一个成员就对于类中的一个成员
-
直接调用属性名即可获取属性值,但返回的类型值是const&常引用类型
-
也可以调用 mutable_成员名 ex:mutable_result()返回的是一个指针类型,可以修改的
-
使用protobuf的列表属性
-
在.proto文件中加上repeated关键字,列表相当于数组,使用也很简单
-
add_成员名 ex:add_friend_list(),调用一次这个函数,下标会自动加一,返回一个指针对象,在用这个指针使用set_XXX来设置成员值
-
可以使用bytes类型来代替string类型