动态使用Protobuf

使用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
#include 
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();
}

你可能感兴趣的:(protobuf)