Message对象

一)描述

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 <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
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);
	.....




 

posted @ 2018-01-27 23:01  jadeshu  阅读(512)  评论(0编辑  收藏  举报