C++ProtoBuf的安裝與使用


安裝(Ubuntu 16.04)

  1. sudo apt-get install autoconf automake libtool curl make g++ unzip
  2. git clone https://github.com/google/protobuf.git
  3. cd protobuf
  4. git submodule update --init --recursive
  5. ./autogen.sh
  6. ./configure
  7. make
  8. make check
  9. sudo make install
  10. sudo ldconfig # refresh shared library cache
  11. 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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM