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);
上面我分别设置了classstudentP
.
的内部结构的值
如何设置 studentP
对象 studObj
的内部结构的值?
我需要为每个内部结构调用 SerializeToString
吗?
截至目前,您的 ProtoBuf 模式仅包含嵌套消息(phone、地址和大学)的定义;但是,不是它们各自在 Student
消息类型中的字段。而且,您不需要在代码中使用单独的结构。它们已经在 protoc
生成的 .pb.h
和 .pb.cc
文件中声明和定义。使用那些。否则,除非您有充分的理由这样做,否则在使用已经为您维护的 serialization/deserialization library/framework 的同时在代码中手动维护这些类型将是弄巧成拙。
更新后的 ProtoBuf 架构将是(观察下面的字段 5、6 和 7):
studentinfo.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;
}
一旦您拥有所需的架构和生成的文件,您就可以继续创建和填充类型,然后序列化消息以通过网络发送并在另一端反序列化。
这是一个完整的工作示例:
main.cpp
#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;
}
输出:
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
文件,了解您可能需要处理消息的修改器和访问器。
我正在学习 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);
上面我分别设置了classstudentP
.
如何设置 studentP
对象 studObj
的内部结构的值?
我需要为每个内部结构调用 SerializeToString
吗?
截至目前,您的 ProtoBuf 模式仅包含嵌套消息(phone、地址和大学)的定义;但是,不是它们各自在 Student
消息类型中的字段。而且,您不需要在代码中使用单独的结构。它们已经在 protoc
生成的 .pb.h
和 .pb.cc
文件中声明和定义。使用那些。否则,除非您有充分的理由这样做,否则在使用已经为您维护的 serialization/deserialization library/framework 的同时在代码中手动维护这些类型将是弄巧成拙。
更新后的 ProtoBuf 架构将是(观察下面的字段 5、6 和 7):
studentinfo.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;
}
一旦您拥有所需的架构和生成的文件,您就可以继续创建和填充类型,然后序列化消息以通过网络发送并在另一端反序列化。
这是一个完整的工作示例:
main.cpp
#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;
}
输出:
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
文件,了解您可能需要处理消息的修改器和访问器。