Message对象
1: 每一个Message对象都包含两个对象:
(1)google::protobuf::Descriptor 描述对象,是Message所有Filed的一个集合,它又包含了
FieldDescriptor 对象; 每个filed都对应一个FieldDescriptor;
(2)google::protobuf::Reflection 反射对象, 通过它 + FieldDescriptor, 能set/get filed对象的值;
2: 每一个Message对象,可以通过统一的对象工厂来构建, 根据协议生成了代码后,只要传入Message的名字,就能构建出对应的Message的类的实例;
#define _CRT_SECURE_NO_WARNINGS #include <string.h> #include <stdlib.h> #include <iostream> #include <string> using namespace std; #include "../proto/person.pb.h" #if 0 int main(int argc, char** argv) { //1.定义要传送数据的对象 对应message后跟的名字 Person p; //2.初始化对象 p.set_name("大圣"); p.set_email("wukong@163.com"); p.set_age(1700); cout << p.name() << " " << p.age() << " " << p.email() << endl; //3.将这个数据对象序列化 string out; p.SerializeToString(&out); //4.使用string对象里面存放的数据,反序列化数据对象 Person monkey; monkey.ParseFromString(out); cout << monkey.name() << " " << monkey.age() << " " << monkey.email() << endl; system("Pause"); return 0; } #else //传递一个信息类型的字符串,那么这个工厂就会帮我们构造出一个对应的类的实例 //"Person"字符串-->Person的实例 -->返回的是一个基类Message类的指针 //基类指针 指向子类实例 //create_message -->delete 来删除对象实例 google::protobuf::Message* create_message(const char* typeName) { //message类 google::protobuf::Message* message = NULL; // 根据名字,找到message的描述对象 const google::protobuf::Descriptor* descriptor = google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(typeName); if (descriptor) { //根据描述对象到对象工厂里面,生成对应的模板对象 const google::protobuf::Message* prototype = google::protobuf::MessageFactory::generated_factory()->GetPrototype(descriptor); if (prototype) { //根据模板对象克隆一个 message = prototype->New(); } } return message; } int main(int argc, char** argv) { //基类的message-->Person类的实例 google::protobuf::Message* msg = create_message("Person"); /* Person* hou = (Person*)msg; hou->set_name("大圣"); cout << hou->name() << endl; */ /* 每个message对象包含两个对象: google::protobuf::Descriptor 描述对象-->获取message的描述信息 字段名以及类型等-->包含每一个field的描述 google::protobuf::Reflection 反射对象--> 使用这个对象 + field描述, 能get/set每个field的值 */ const google::protobuf::Descriptor* des = msg->GetDescriptor(); const google::protobuf::Reflection* ref = msg->GetReflection(); //设置 // name // 1. 通过des获取 const google::protobuf::FieldDescriptor* fd_des = des->FindFieldByName("name"); //通过字段名字设置数据 // 2.通过ref进行设置 ref->SetString(msg, fd_des, "大圣"); //age fd_des = des->FindFieldByNumber(2); //通过字段标识号设置数据 ref->SetInt32(msg, fd_des, 1500); //email fd_des = des->FindFieldByName("email"); ref->SetString(msg, fd_des, "wukong@163.com"); //数组 使用AddInt32一个一个追加进去 fd_des = des->FindFieldByName("set"); ref->AddInt32(msg, fd_des, 1); ref->AddInt32(msg, fd_des, 2); ref->AddInt32(msg, fd_des, 3); ref->AddInt32(msg, fd_des, 4); //获取 for (int i = 0; i < des->field_count(); i++) { //获取每一个field描述对象 const google::protobuf::FieldDescriptor* fd = des->field(i); //(1) 获取名字 cout << fd->name() << endl; //字段名字 不是数据 如:name age cout << fd->type_name() << endl; //类型 cout << fd->cpp_type_name() << endl; //c++类型 bytes被换成了string // 判断字段规则 // fd->is_repeated() 是否是数组 // fd->is_optional() 是否是非必须 // fd->is_required() 是否是必须 if (!fd->is_repeated()) { //获取数据 switch (fd->cpp_type()) { case google::protobuf::FieldDescriptor::CppType::CPPTYPE_INT32: cout << ref->GetInt32(*msg, fd) << endl; break; case google::protobuf::FieldDescriptor::CppType::CPPTYPE_STRING: cout << ref->GetString(*msg, fd) << endl; break; } } else { for (int j = 0; j < ref->FieldSize(*msg, fd); j++) //ref->FieldSize(*msg, fd)获取数组长度 { switch (fd->cpp_type()) { case google::protobuf::FieldDescriptor::CppType::CPPTYPE_INT32: cout << ref->GetRepeatedInt32(*msg, fd,j) << " "; //使用GetRepeatedInt32 便利数组 break; case google::protobuf::FieldDescriptor::CppType::CPPTYPE_STRING: cout << ref->GetRepeatedString(*msg, fd,j) << " "; break; } } cout << endl; } cout << fd->number() << endl; //获取字段标识号 } //删除 delete msg; system("Pause"); return 0; } #endif