天天看點

【Protocol Buffer】Protocol Buffer入門教程(六):枚舉和包

00. 目錄

文章目錄

    • 01. 枚舉消息格式
    • 02. 枚舉測試代碼
    • 03. 編譯和測試
    • 04. 包的消息格式
    • 05. 包的測試程式
    • 06. 編譯和測試
    • 07. 附錄

當需要定義一個消息類型的時候,可能想為一個字段指定某“預定義值序列”中的一個值,這時候可以通過枚舉實作。

syntax = "proto3";//指定版本資訊,不指定會報錯     message Person //message為關鍵字,作用為定義一種消息類型     {         string name = 1;    //姓名         int32 id = 2;       //id         string email = 3; //郵件         enum PhoneType //枚舉消息類型         {             MOBILE = 0; //proto3版本中,首成員必須為0,成員不應有相同的值             HOME = 1;             WORK = 2;         }         message PhoneNumber         {             string number = 1;             PhoneType type = 2;         }         repeated PhoneNumber phones = 4; //phones為數組     }     message AddressBook     {         repeated Person people = 1;     }           

生成對應檔案

deng@itcast:/mnt/hgfs/LinuxHome/day03$ protoc addressbook.proto --cpp_out=./     deng@itcast:/mnt/hgfs/LinuxHome/day03$           

#include "addressbook.pb.h"     #include <iostream>     #include <fstream>     using namespace std;     void set_addressbook()     {         AddressBook obj;         Person *p1 = obj.add_people(); //新增加一個Person         p1->set_name("tom");         p1->set_id(1);         p1->set_email("[email protected]");         Person::PhoneNumber *phone1 = p1->add_phones(); //增加一個phone         phone1->set_number("110");         phone1->set_type(Person::MOBILE);         Person::PhoneNumber *phone2 = p1->add_phones(); //增加一個phone         phone2->set_number("120");         phone2->set_type(Person::HOME);         fstream output("pb.itcast", ios::out | ios::trunc | ios::binary);         bool flag = obj.SerializeToOstream(&output);//序列化         if (!flag)         {             cerr << "Failed to write file." << endl;             return;         }         output.close();//關閉檔案     }     void get_addressbook()     {         AddressBook obj;         fstream input("./pb.itcast", ios::in | ios::binary);         obj.ParseFromIstream(&input);  //反序列化         input.close(); //關閉檔案         for (int i = 0; i < obj.people_size(); i++)         {             const Person& person = obj.people(i);//取第i個people             cout << "第" << i + 1 << "個資訊\n";             cout << "name = " << person.name() << endl;             cout << "id = " << person.id() << endl;             cout << "email = " << person.email() << endl;             for (int j = 0; j < person.phones_size(); j++)             {                 const Person::PhoneNumber& phone_number = person.phones(j);                 switch (phone_number.type())                 {                 case Person::MOBILE:                     cout << "  Mobile phone #: ";                     break;                 case Person::HOME:                     cout << "  Home phone #: ";                     break;                 case Person::WORK:                     cout << "  Work phone #: ";                     break;                 }                 cout << phone_number.number() << endl;             }             cout << endl;         }     }     int main()     {         // Verify that the version of the library that we linked against is         // compatible with the version of the headers we compiled against.         GOOGLE_PROTOBUF_VERIFY_VERSION;         set_addressbook(); //序列化         get_addressbook(); //反序列化         // Optional:  Delete all global objects allocated by libprotobuf.         google::protobuf::ShutdownProtobufLibrary();         return 0;     }           

編譯和測試結果

deng@itcast:/mnt/hgfs/LinuxHome/day03$ g++  test.cpp addressbook.pb.cc `pkg-config --libs --cflags protobuf`     deng@itcast:/mnt/hgfs/LinuxHome/day03$ ./a.out      第1個資訊     name = tom     id = 1     email = [email protected]       Mobile phone #: 110       Home phone #: 120     deng@itcast:/mnt/hgfs/LinuxHome/day03$           
【Protocol Buffer】Protocol Buffer入門教程(六):枚舉和包

.proto檔案新增一個可選的package聲明符,用來防止不同的消息類型有命名沖突。包的聲明符會根據使用語言的不同影響生成的代碼。對于C++,産生的類會被包裝在C++的命名空間中。

syntax = "proto3";//指定版本資訊,不指定會報錯     package tutorial; //package聲明符     message Person //message為關鍵字,作用為定義一種消息類型     {         string name = 1;    //姓名         int32 id = 2;       //id         string email = 3; //郵件         enum PhoneType //枚舉消息類型         {             MOBILE = 0; //proto3版本中,首成員必須為0,成員不應有相同的值             HOME = 1;             WORK = 2;         }         message PhoneNumber         {             string number = 1;             PhoneType type = 2;         }         repeated PhoneNumber phones = 4; //phones為數組     }     message AddressBook     {         repeated Person people = 1;     }           

#include "addressbook.pb.h"     #include <iostream>     #include <fstream>     using namespace std;     void set_addressbook()     {         tutorial::AddressBook obj;         tutorial::Person *p1 = obj.add_people(); //新增加一個Person         p1->set_name("tom");         p1->set_id(1);         p1->set_email("[email protected]");         tutorial::Person::PhoneNumber *phone1 = p1->add_phones(); //增加一個phone         phone1->set_number("110");         phone1->set_type(tutorial::Person::MOBILE);         tutorial::Person::PhoneNumber *phone2 = p1->add_phones(); //增加一個phone         phone2->set_number("120");         phone2->set_type(tutorial::Person::HOME);         fstream output("pb.itcast", ios::out | ios::trunc | ios::binary);         bool flag = obj.SerializeToOstream(&output);//序列化         if (!flag)         {             cerr << "Failed to write file." << endl;             return;         }         output.close();//關閉檔案     }     void get_addressbook()     {         tutorial::AddressBook obj;         fstream input("./pb.itcast", ios::in | ios::binary);         obj.ParseFromIstream(&input);  //反序列化         input.close(); //關閉檔案         for (int i = 0; i < obj.people_size(); i++)         {             const tutorial::Person& person = obj.people(i);//取第i個people             cout << "第" << i + 1 << "個資訊\n";             cout << "name = " << person.name() << endl;             cout << "id = " << person.id() << endl;             cout << "email = " << person.email() << endl;             for (int j = 0; j < person.phones_size(); j++)             {                 const tutorial::Person::PhoneNumber& phone_number = person.phones(j);                 switch (phone_number.type())                 {                 case tutorial::Person::MOBILE:                     cout << "  Mobile phone #: ";                     break;                 case tutorial::Person::HOME:                     cout << "  Home phone #: ";                     break;                 case tutorial::Person::WORK:                     cout << "  Work phone #: ";                     break;                 }                 cout << phone_number.number() << endl;             }             cout << endl;         }     }     int main()     {         // Verify that the version of the library that we linked against is         // compatible with the version of the headers we compiled against.         GOOGLE_PROTOBUF_VERIFY_VERSION;         set_addressbook(); //序列化         get_addressbook(); //反序列化         // Optional:  Delete all global objects allocated by libprotobuf.         google::protobuf::ShutdownProtobufLibrary();         return 0;     }           

編譯和測試

deng@itcast:/mnt/hgfs/LinuxHome/day03$ g++  test.cpp addressbook.pb.cc `pkg-config --libs --cflags protobuf`     deng@itcast:/mnt/hgfs/LinuxHome/day03$ ./a.out      第1個資訊     name = tom     id = 1     email = [email protected]       Mobile phone #: 110       Home phone #: 120     deng@itcast:/mnt/hgfs/LinuxHome/day03$           
【Protocol Buffer】Protocol Buffer入門教程(六):枚舉和包

繼續閱讀