一、安装
1、从github上下载:https://github.com/protocolbuffers/protobuf/tree/v3.12.0
2、cd protobuf-3.12.0
3、./autogen.sh
如果出现autoreconf: command not found
yum install -y autoconf automake libtool
---- 此步会生成./configure脚本!
4、./configure
5、make
6、make install
---- 完成后头文件、lib和protoc可执行文件分别在/usr/local/include/google/protobuf、/usr/local/lib和/usr/local/bin里
7、protoc --version
有输出,安装成功
二、编写proto文件、生成对应.h .cc
my_struct.proto
syntax = "proto3";
package myProto;
import "google/protobuf/wrappers.proto";
message Person
{
enum PhoneType
{
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber
{
string number = 1;
PhoneType type = 2;
}
string name = 1;
int32 age = 2;
string email = 3;
repeated PhoneNumber phone = 4;
bytes code = 5;
google.protobuf.BoolValue is_male = 6;
bool is_female = 7;
}
生存.h .cc到当前目录
protoc *.proto --cpp_out=./
三、使用
1、修改CMakelist.txt
target_link_libraries中添加-lprotobuf
包上pb生成头文件
2、
#include <stdio.h>
#include "protobuf/my_struct.pb.h"
#include <string>
std::string createNewPerson(const std::string& name,int age, const std::string& email)
{
myProto::Person p;
p.set_name(name);
p.set_age(age);
p.set_email(email);
printf("before mutable p.has_is_male():%d\n", p.has_is_male());
google::protobuf::BoolValue* isMale = p.mutable_is_male();
printf("after mutable p.has_is_male():%d\n", p.has_is_male());
//isMale->set_value(true);
p.set_is_female(false);
auto* phone1 = p.add_phone();
phone1->set_type(myProto::Person_PhoneType_HOME);
phone1->set_number("85325677");
auto* phone2 = p.add_phone();
phone2->set_type(myProto::Person_PhoneType_MOBILE);
phone2->set_number("12345676668");
char code[64] = "sdwqesdfhsdfjhjgf1aerfsdfcsdfdsfsadfsdfsasdasdadassasdasdsdadad";
p.set_code(code);
printf("createNewPerson!\n");
p.PrintDebugString();
return p.SerializeAsString();
}
void introduceP(const std::string& str)
{
myProto::Person p;
p.ParseFromString(str);
printf("\nintroduceP!\n");
p.PrintDebugString();
printf("Although is_male mutable but not set_value before SerializeAsString\n");
printf("p.has_is_male():%d\n", p.has_is_male());
google::protobuf::BoolValue* isMale = p.mutable_is_male();
printf("isMale->is_male():%d\n", isMale->value());
isMale->set_value(true);
printf("isMale->is_male():%d\n", isMale->value());
printf("p.is_female():%d\n",p.is_female());
}
struct Person {
enum PhoneType {
MOBILE = 0,
HOME = 1,
WORK = 2,
};
struct PhoneNumber {
std::string number;
PhoneType type;
};
std::string name;
int age;
std::string email;
PhoneNumber phone;
};
int main()
{
std::string person = createNewPerson("D-ddd",29,"244xxxxxx@qq.com");
introduceP(person);
return 0;
}
打印输出有点乱,可以再改下proto,在my_struct.proto的Person类前,新增一层message,将一类结构,放在一起
message my_interface{
Person person = 1;
}
用的地方也修改一下,同时打印调用my_interface的打印
myProto::my_interface myIf;
auto* p = myIf.mutable_person();
if(p==nullptr) return "";
// set data
myIf.PrintDebugString();
如此即包含了结构的名字,又方便查看log中pb结构的启始和结尾位置。
google.protobuf.BoolValue类型和bool类型区别(其他类似,如int32和google.protobuf.Int32Value)
bool类型就是内置类型,普通的bool
google.protobuf.BoolValue类型的本质也是message,需要mutable_xxx分配内存,写时用set_value(true),读数据时也需要先判断has_xxx()
大小上google.protobuf.BoolValue类型也要大一点
四、初探Arena
1、开启arena
.proto文件中加入下面这句
option cc_enable_arenas = true;
2、使用arena
一开始还以为开启了,就是用了,结果bm测时间也没啥优化,还劣化了不少…
打印了下CreateMessageInternal里面的判断条件,发现arena都等于NULL…
//myArenaProto::my_interface myIf;
Arena arena;
myArenaProto::my_interface* myIf = google::protobuf::Arena::CreateMessage<myArenaProto::my_interface>(&arena);;
参考:
https://blog.youkuaiyun.com/hsy12342611/article/details/129914975
https://blog.youkuaiyun.com/qq_43762191/article/details/119921304