天天看点

【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入门教程(六):枚举和包

继续阅读