动态使用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<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();
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
动态生成protobuf数据模型可以通过以下步骤实现: 1. 定义msgId和标准的proto协议:首先,你需要定义msgId和标准的proto协议。msgId是用来标识每个消息的唯一标识符,而标准的proto协议定义了消息的结构和字段。 2. 生成对应语言的protobuf协议代码:使用标准的proto协议文件,你可以使用相应语言的protobuf编译器来生成对应语言的protobuf协议代码。例如,使用protoc编译器可以将proto文件编译成Java、C++、Python等语言的protobuf代码。 3. 生成msgId与msgName之间的映射:根据你的需求,你可以生成一个映射表,将msgId与msgName进行关联。这样,在使用动态生成的protobuf数据模型时,你可以根据msgId来获取对应的msgName。 4. 将描述模型的协议写入ProtocolBuilder项目中的.code文件:最后,将生成的protobuf协议代码写入ProtocolBuilder项目中的.code文件中,以便在项目中使用动态生成的protobuf数据模型。 下面是一个示例代码,演示了如何动态生成protobuf数据模型: ```python # 定义msgId和标准的proto协议 msgId = 1 proto = """ syntax = "proto3"; message MyMessage { string name = 1; int32 age = 2; } """ # 生成对应语言的protobuf协议代码 import subprocess subprocess.run(["protoc", "--python_out=.", "my_proto.proto"]) # 生成msgId与msgName之间的映射 msg_mapping = {msgId: "MyMessage"} # 将描述模型的协议写入ProtocolBuilder项目中的.code文件 with open("ProtocolBuilder.code", "w") as f: f.write(proto) print("动态生成protobuf数据模型成功!") ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员的资料库

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值