C++ProtoBuf的安装与使用
Posted smallblackegg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ProtoBuf的安装与使用相关的知识,希望对你有一定的参考价值。
安装(Ubuntu 16.04)
- sudo apt-get install autoconf automake libtool curl make g++ unzip
- git clone https://github.com/google/protobuf.git
- cd protobuf
- git submodule update --init --recursive
- ./autogen.sh
- ./configure
- make
- make check
- sudo make install
- sudo ldconfig # refresh shared library cache
- protoc --version
如果能查看proto的版本,则代表安装成功,否则失败。
简介
本文主要介绍proto3的使用以及个人理解。关于proto版本的不同以及深入理解,可以参考下面链接。
https://www.jianshu.com/p/5e65f33c4b15?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation ???//数据传输格式
proto2
https://www.jianshu.com/p/e89594ecc1db
proto3
https://blog.csdn.net/u011518120/article/details/54604615
用法
proto3
/*****PbTest.proto******/
syntax = "proto3";
package tutorial;
message Person
string name = 1;
int32 id = 2;
string email = 3;
enum PhoneType
MOBILE = 0;
HOME = 1;
WORK = 2;
message PhoneNumber
string number = 1;
PhoneType type = 2;
repeated PhoneNumber phones = 4;
message AddressBook
Person people = 1;
protoc --cpp_out=. PbTest.proto //先编译proto文件生成.cc和.h文件
若对proto文件进行修改,则需要重新使用protoc进行编译,生成新的cc和h文件。
#include <iostream>
#include "PbTest.pb.h"
void BookAdd(tutorial::Person *person)
person->set_email("fun@qq.com");
person->set_name("fun_name");
person->set_id(1111);
tutorial::Person::PhoneNumber *phone_num=person->add_phones();
phone_num->set_number("1999");
int main()
tutorial::Person test;
test.set_id(2111);
test.set_name("main_name");
test.set_email("main@qq.com");
tutorial::Person::PhoneNumber phone_num;
phone_num.set_number("2119");
phone_num.set_type(tutorial::Person::WORK);
// tutorial::Person_PhoneNumber phone; //等价上面的phone_num
// phone.set_number("2119");
// phone.set_type(tutorial::Person_PhoneType::Person_PhoneType_HOME);
// std::cout<<phone.number()<<std::endl;
// std::cout<<phone.type()<<std::endl;
tutorial::AddressBook book;
BookAdd(book.mutable_people());
// book.mutable_people()->set_name("main2test"); //与BookAdd函数调用等价
std::cout<<"main id :"<<test.id()<<std::endl;
std::cout<<"main name :"<<test.name()<<std::endl;
std::cout<<"main email :"<<test.email()<<std::endl;
std::cout<<"main phone :"<<phone_num.number()<<std::endl;
std::cout<<"main phone type :"<<phone_num.type()<<std::endl;
const tutorial::Person &person=book.people();
std::cout<<"AddBook id :"<<person.id()<<std::endl;
std::cout<<"AddBook name :"<<person.name()<<std::endl;
std::cout<<"AddBook email :"<<person.email()<<std::endl;
const tutorial::Person::PhoneNumber &num_phone=person.phones(0);
std::cout<<"AddBook phone :"<<num_phone.number()<<std::endl;
std::cout<<"AddBook phone type:"<<num_phone.type()<<std::endl;
return 0;
g++ main.cc PbTest.pb.cc -lprotobuf -lpthread
输出结果
main id :2111
main name :main_name
main email :main@qq.com
main phone :2119
main phone type :2
AddBook id :1111
AddBook name :fun_name
AddBook email :fun@qq.com
AddBook phone :1999
AddBook phone type:0
总结
????关于proto3的使用过程中,与proto2比较起来,3去掉了字段的限制,以及默认值。虽然说3去掉了[default=value]的操作,但是3在枚举类型中,必须要从0开始,并且枚举的默认值也为0。对于bool类型,默认是false。正因为由于3有了默认值的操作,所以在判断是用户赋予的值还是默认值,则需要话费一些功夫去判断。(由于本人不常用,有需要者,可以百度。)
????如果需要使用oneof字段时,它的原理有点类似与共享(union)结构体。如果数据结构复杂的话,也可以采用c++中的map来存储key-value结构。value也可以是proto中的message类型。
????踩坑:如果字段前面有repeated修饰的话,对其进行修改的时候则需要通过proto对象中的add_()方法对内部嵌套的字段进行赋值。若没有的话,则可以采用 obj.mutable_()->set_()来进行赋值。
若需要参考proto2代码,则可以参考:
https://github.com/protobuf-c/protobuf-c/wiki/Examples
https://github.com/SmallBlackEgg/proto/
以上是关于C++ProtoBuf的安装与使用的主要内容,如果未能解决你的问题,请参考以下文章