一)描述
1: 每一个Message对象都包含两个对象:
(1)google::protobuf::Descriptor 描述对象,是Message所有Filed的一个集合,它又包含了FieldDescriptor 对象; 每个filed都对应一个FieldDescriptor;
(2)google::protobuf::Reflection 反射对象, 通过它 + FieldDescriptor,能set/get filed对象的值;
2: 每一个Message对象,可以通过统一的对象工厂来构建, 根据协议生成了代码后,只要传入Message的名字,就能构建出对应的Message的类的实例;
二)构建message
1: 根据消息的名字来构建对应的Message类型的C++实例
google::protobuf::Message* create_message(const char* typeName) { 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; }
2: 删除Message: delete操作
3: 返回一个基类的指针,指向一个子类的实例;
#include#include #include #include using namespace std;#include "../proto/person.pb.h"//根据字符串类名创建实例google::protobuf::Message* create_message(const char* typeName) { 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* agrv[]){ //====================================普通创建对象=================================#pragma region customNew Person p; p.set_name("jadeshu"); p.set_age(24); p.set_email("jadeshu@qq.com"); printf("%s %s %d\n",p.name().c_str(),p.email().c_str(),p.age()); //反序列化 string strout(""); p.SerializeToString(&strout); Person jadeshu; jadeshu.ParseFromString(strout); //printf("%s %s %d\n",jadeshu.name().c_str(),jadeshu.email().c_str(),jadeshu.age()); cout << jadeshu.name() <<" " << jadeshu.email()<<" " << jadeshu.age() << endl; //================================================================================== printf("===============================================\n");#pragma endregion customNew#pragma region MessageNew //创建实例 //基类的message---->Person的实例 google::protobuf::Message* pMsgObj = create_message("Person"); Person* perCur = (Person*)pMsgObj; perCur->set_name("wudi"); perCur->set_age(50); perCur->set_email("xxxx@qq.com"); cout << perCur->name() <<" " << perCur->email()<<" " << perCur->age() << endl; //删除pMsgObj delete pMsgObj;#pragma endregion system("pause"); return 0;}
三)Message获取filed描述
1: 遍历每个filed;
const Descriptor* descriptor = message->GetDescriptor(); for (int32_t index = 0; index < descriptor->field_count(); ++index) { const FieldDescriptor* fd = descriptor->field(index); const string& name = fd->name(); }
2: filed:
name: filed的文本名字;
is_required:是否为required 选项;
is_repeated:是否为数组;
cpp_type:返回类型;
四)Message设置filed
1: 获取Reflection
2: 根据对应的每个字段描述的类型,来设置字段;
根据字段的类型fd->ccp_type(),使用Reflection对象来设置Messsage的每一个filed;
FieldDescriptor::CPPTYPE_ENUM FieldDescriptor::CPPTYPE_UINT64 FieldDescriptor::CPPTYPE_MESSAGE 成员: reflection->SetDouble(message, fd, value); ..... 数组: reflection->AddDouble(message, fd, value); .....