簡體   English   中英

C++ protobuf 如何設置嵌套結構的值

[英]C++ protobuf how to set values for nested struct

我正在學習 C++ ProtoBuf。

我有以下需要序列化的結構:

enum phonetype
{
    DESKPHONE,
    MOBILE,
    WIRELESSPHONE
};

struct phonenumber
{
    int ptype;
    string number;
};

struct address
{
    string addr1;
    string addr2;
};

struct college
{
    string collegename;
    string collegeaddress;
};

struct student
{
    int id;
    string name;
    double age;
    string email;

    struct phonenumber phoneN;
    struct address addr;
    struct college col;
};

我已按如下方式初始化結構:

student stud = {123, "Stud_1", 30, "none",
                    {MOBILE, "123456789"}, 
                    {"Boston, US", "None"}, 
                    {"Boston college", "Boston"}};

現在我想創建這個結構的序列化字符串,為此我編寫了以下.proto文件:

syntax = "proto2";

message studentP
{
  required int32 id = 1;
  required string name = 2;
  required double age = 3;
  optional string email = 4;

  message phonenumberP
  {
    required int32 ptype = 1;
    required string number = 2;
  }
  
  message addressP {
    required string addr1 = 1;
    optional string addr2 = 2;
  }

  message collegeP {
    required string collegename = 1;
    optional string collegeaddress = 2;
  }  
}

在我的 C++ 代碼中,我將 proto obj 值設置如下:

studentP studObj;
studObj.set_name(stud.name);
studObj.set_eid(stud.id);
studObj.set_age(stud.age);

studentP::phonenumberP *phone;
phone->set_ptype(stud.phoneN.ptype);
phone->set_number(stud.phoneN.number);

studentP::addressP *addr;
addr->set_addr1(stud.addr.addr1);
addr->set_addr2(stud.addr.addr2);

studentP::collegeP *coll;
coll->set_collegename(stud.col.collegename);
coll->set_collegeaddress(stud.col.collegeaddress);


string student_str;
studObj.SerializeToString(&student_str);

上面我已經分別設置了 class studentP的內部結構的值。

如何設置studentP object studObj的內部結構的值?

我需要為每個內部結構調用SerializeToString嗎?

到目前為止,您的 ProtoBuf 模式僅包含嵌套消息(電話、地址和大學)的定義; 但是,不是Student消息類型中它們各自的字段。 而且,您不需要在代碼中使用單獨的結構。 它們已經在protoc生成的.pb.h.pb.cc文件中聲明和定義。 使用那些。 否則,在使用已經為您執行此操作的序列化/反序列化庫/框架的同時手動維護代碼中的這些類型將是弄巧成拙,除非您有充分的理由這樣做。

更新后的 ProtoBuf 模式將是(觀察下面的字段 5、6 和 7):

學生信息.proto

syntax = "proto2";

package test;

message Student
{
    required int32 id = 1;
    required string name = 2;
    required double age = 3;
    optional string email = 4;

    enum PhoneType
    {
        DESK = 1;
        MOBILE = 2;
        WIRELESS = 3;
    };

    message Phone
    {
        required PhoneType type = 1;
        required string number = 2;
    }

    message Address {
        required string address1 = 1;
        optional string address2 = 2;
    }

    message College {
        required string name = 1;
        optional string address = 2;
    }

    required Phone phone = 5;
    required Address address = 6;
    optional College college = 7;
}

一旦您擁有所需的架構和生成的文件,您就可以 go 創建和填充類型,然后序列化消息以通過線路發送並在另一端反序列化。

這是一個完整的工作示例:

主文件

#include <iostream>
#include <string>
#include "studentinfo.pb.h"

int main()
{
    using namespace test;

    // Serialization

    Student s;
    s.set_name("Test");
    s.set_id(123);
    s.set_age(24);

    s.mutable_phone()->set_type(Student_PhoneType_DESK);
    s.mutable_phone()->set_number("+00 123 1234567");

    s.mutable_address()->set_address1("House # 1, Street # 1");
    s.mutable_address()->set_address2("House # 2, Street # 2");

    s.mutable_college()->set_name("XYZ College");
    s.mutable_college()->set_address("College Address Here");

    std::cout << "Serialization:\n\n" << s.DebugString() << "\n\n";
    //s.PrintDebugString();

    std::string serialized;
    if ( !s.SerializeToString( &serialized ) )
    {
        std::cerr << "ERROR: Unable to serialize!\n";
        return -1;
    }

    // Deserialization

    Student deserialized;
    if ( !deserialized.ParseFromString( serialized ) )
    {
        std::cerr << "ERROR: Unable to deserialize!\n";
        return -1;
    }

    std::cout << "Deserialization:\n\n";
    deserialized.PrintDebugString();

    // deserialized.name();
    // deserialized.id();
    // ...
    // deserialized.phone().type();
    // deserialized.phone().number()
    // ...

    return 0;
}

Output:

Serialization:

id: 123
name: "Test"
age: 24
phone {
  type: DESK
  number: "+00 123 1234567"
}
address {
  address1: "House # 1, Street # 1"
  address2: "House # 2, Street # 2"
}
college {
  name: "XYZ College"
  address: "College Address Here"
}


Deserialization:

id: 123
name: "Test"
age: 24
phone {
  type: DESK
  number: "+00 123 1234567"
}
address {
  address1: "House # 1, Street # 1"
  address2: "House # 2, Street # 2"
}
college {
  name: "XYZ College"
  address: "College Address Here"
}

查看.pb.h文件,了解您可能需要操作消息的修改器和訪問器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM