最近在弄proto2 升级成 proto3的内容(1)
复习一下proto3的内容,不全是原创
syntax = “proto3”;
package test_2;
//枚举变量第一个必须是0
enum PlayerType
{
NO = 0; //msg.proto:9:11: The first enum value must be zero in proto3.
XS = 1;
CNR = 3;
};
message usr_login
{
string usrname = 1;
string usrpasswd = 2;
}
message usr_info
{
int32 classrome = 1;
string studentID = 2;
PlayerType type = 4;
}
message student
{
//required int32 STAMP = 1; //Required fields are not allowed in proto3.
//optional int32 STAMP = 1;// This file contains proto3 optional fields, but --experimental_allow_proto3_optional was not set.
//singular int32 STAMP = 1;//Missing field number.
//int32 STAMP = 1[default=99];// Explicit default values are not allowed in proto3.
int32 STAMP = 1;
usr_login usrLogin = 2;
repeated usr_info array = 3;
}
//编译proto命令
// protoc msg.proto --cpp_out=.
//编译代码
// g++ -o t.exe testproto3.cpp msg.pb.cc -l protobuf
测试proto3的代码
#include <assert.h>
#include
#include “msg.pb.h”
using namespace std;
using namespace test_2; //这个是protobuf所定义的命名空间
int main()
{
student stud; //学生对象
cout<<"00 ByteSize = "<<stud.ByteSize()<<endl; //0
//1.对于int类型的只提供获取,修改和清楚三个API
stud.set_stamp(999);
cout<<"11 ByteSize = "<<stud.ByteSize()<<endl; //3
//2.消息中的自定义类型,并没有set借口,而是要通过mutable_*接口
auto usrLoginPtr = stud.mutable_usrlogin();
cout<<"1.5 ByteSize = "<<stud.ByteSize()<<endl; //5
usrLoginPtr->set_usrname(string("321"));
cout<<"22 ByteSize = "<<stud.ByteSize()<<endl; //10
string passwd("123");
usrLoginPtr->set_usrpasswd(passwd);
cout<<"33 ByteSize = "<<stud.ByteSize()<<endl; //15
string studentID("888");
for(int i =0;i<2;i++)
{
//对于repeated的类型,add_*()接口增加一条记录
auto arrPtr = stud.add_array(); //增加一个
cout<<"for: "<<i<<" star ByteSize = "<<stud.ByteSize()<<endl; //17 27
arrPtr->set_classrome(369);
cout<<"for: "<<i<<" mid ByteSize = "<<stud.ByteSize()<<endl; //20 30
arrPtr->set_studentid(studentID); //studentID
cout<<"for: "<<i<<" end ByteSize = "<<stud.ByteSize()<<endl; //25 35
if(i == 1)
{
arrPtr->set_type(CNR); //赋值为3
cout<<"for: "<<i<<" add enum ByteSize = "<<stud.ByteSize()<<endl; //37
}
}
cout<<"************************* ByteSize = "<<stud.ByteSize()<<endl; //37
//进行序列化变成字符串
string buff;
bool isSucceed = stud.SerializePartialToString(&buff);
//cout<<"buff :"<<buff.c_str();
assert(isSucceed == true);
char writeBlock[100] = {}; //写缓存
memset(writeBlock,0,sizeof(writeBlock));
stud.SerializeToArray(writeBlock,stud.ByteSize()); //这个是存入数据中
int allLen = stud.ByteSize();
//反序列化
//1.通过 string 获得
student res;
isSucceed = res.ParseFromString(buff);
assert(isSucceed == true);
//2.通过数组获得
student ret;
ret.ParseFromArray(writeBlock,allLen);
cout<<"ParseFromArray stamp: "<<ret.stamp()<<endl;//999
//注意读取自定义的方式
auto loginPtr = ret.mutable_usrlogin(); //usrLogin
cout<<"loginPtr usrname: "<<loginPtr->usrname().c_str()<<endl;//321
cout<<"loginPtr usrpasswd: "<<loginPtr->usrpasswd().c_str()<<endl;//123
cout<<"ret.array_size(): "<< ret.array_size()<<endl; //2
//遍历数组
for(int i =0;i< ret.array_size();i++)
{
//获得一个该下标的元素的引用
//返回值为const类型的,不能通过该返回值去进行修改
auto tmpobj = ret.array(i);
cout<<"tmpPtr "<<i<<" classrome:"<<tmpobj.classrome()
<<" studentID:"<<tmpobj.studentid().c_str()
<<" type: "<<tmpobj.type()<<endl;
// tmpPtr 0 classrome:369 studentID:888 type: 0
// tmpPtr 1 classrome:369 studentID:888 type: 3
}
return 0;
}