使用pb动态特性
1:动态编译proto文件
构造 google::protobuf::compiler::Importer 对象
调用FileDescriptor * fd = im.import(“协议文件”);
(1)新建一个空项目(预编译头不要选定)
c/c++->常规->附加包含目录->E:\protobuf-2.6.1\src
链接器->常规->附加库目录->E:\protobuf-2.6.1\vsprojects\Debug
链接器->输入->附加依赖项->libprotobuf.lib
(2)新建一个TestPBmain.cpp
(3)新建一个协议文件”test.proto”放在E盘的proto目录下
message test
{
required int32 id=1;
required string name=2;
}
2:动态生成Message对象
Descriptor * desc = fd->pool()->FindMessageTypeByName(msgname)
构造google::protobuf::MessageFactory * factory= new DynamicMessageFactory (fd->pool);
Message * msg = factory->getProtype(desc)->new();
3:动态get/set数据
FieldDescriptor * field = desc->FindFieldByName(“field name”);
Reflection * ref = msg->GetReflection();
ref->setint32(msg,field,5);
int32 value = ref->getInt32(*msg,field);
4:代码示例:
#include"google/protobuf/compiler/importer.h"
#include"google/protobuf/dynamic_message.h"
#include<string.h>
#include <iostream>
using namespace std;
using namespace google::protobuf::compiler;
using namespace google::protobuf;
class MyMultiFileErrorCollector :public MultiFileErrorCollector {
void AddError(const string& filename, int line, int column,
const string& message) {
}
};
void main()
{
//定义DiskSourceTree,MultiFileErrorCollector的原因可查看Importer的构造函数。
DiskSourceTree dt;
MyMultiFileErrorCollector collect;//MultiFileErrorCollector是一个抽象类
//新建一个协议文件"test.proto"放在E盘的proto目录下
dt.MapPath("","E:/proto");
//定义一个Impoter的变量
Importer im(&dt, &collect);
//调用FileDescriptor * fd = im.import("协议文件");
const FileDescriptor * fd = im.Import("test.proto");
//动态生成Message对象
const Descriptor * desc = fd->pool()->FindMessageTypeByName("test");
//构造消息工厂
MessageFactory * factory= new DynamicMessageFactory(fd->pool());
//通过工厂构造消息
Message * msg = factory->GetPrototype(desc)->New();
//动态get/set数据
const FieldDescriptor * fieldID = desc->FindFieldByName("id");
const FieldDescriptor * fieldName = desc->FindFieldByName("name");
const Reflection * ref = msg->GetReflection();
ref->SetInt32(msg, fieldID, 5);
ref->SetString(msg, fieldName, "XiaoMing");
int32 value = ref->GetInt32(*msg, fieldID);
string name = ref->GetString(*msg, fieldName);
cout << value << endl;
cout << name << endl;
getchar();
}