动态使用Protobuf
使用pb动态特性步骤
1、动态编译proto文件
构造 google::protobuf::compiler::Importer 对象
调用FileDescriptor * fd = im.import(“协议文件”);
新建一个协议文件:test.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、编译命令
g++ -std=c++11 main.cc -o main -lprotobuf -lpthread
代码示例: #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) { } }; int main(int argc, const char** argv) { //定义DiskSourceTree,MultiFileErrorCollector 的原因可查看Importer的构造函数 DiskSourceTree dt; MyMultiFileErrorCollector collect;//MultiFileErrorCollector 是一个抽象类 //新建一个协议文件"test.proto"放在/root/src/example02/test目录下 dt.MapPath("","/root/src/example02/test"); //定义一个Impoter 对象im 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(); return 0; }