动态使用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;
}
原文地址:https://www.cnblogs.com/hgrical/p/10315826.html