rust下根据protobuf的消息名创建对象实例(代码片段)

跨链技术践行者 跨链技术践行者     2023-01-01     338

关键词:

在C++里面, 我们可以根据一个消息的名称, 动态的创建一个实例

1

2

3

4

5

6

google::protobuf::Descriptor* desc =

    google::protobuf::DescriptorPool::generated_pool()

        ->FindMessageTypeByName("mypkg.MyType");

google::protobuf::Message* message =

    google::protobuf::MessageFactory::generated_factory()

        ->GetPrototype(desc)->New();

这个在protobuf里面是集成进去了, 在其他语言也有类似的东西. 

通过这个, 我们就让轻松实现编解码库, 而不需去构造一个映射表.

但是, 但是在rust里面, 是没有这种东西的. 比较难的地方是rust全局变量必须要实现Send trait, 否则是不能被共享的, 这样做确实安全, 但是对于我们实现MessageFactory就变得困难.

好在rust有thread_local和build.rs, 我们可以通过build.rs在编译proto文件的时候去遍历, 把每个消息添加到一个thread_local的hash map里面去, 从而曲线救国.

不说实现细节, 可以自己去看源码, 这边说如何使用和集成.

1. 创建一个子工程, 名字叫proto

然后将依赖添加进去:

[dependencies]
protobuf = "2.8.0"

[build-dependencies]
protoc-rust = "2.8.0"
protobuf_message_factory = "0.1.2"

2. 把所有的.proto文件都添加到src目录下面去

3. 添加一个build.rs文件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

extern crate protobuf_message_factory;

use protobuf_message_factory::*;

...

fn main()

    let proto_path = "src/";

    let proto_files = get_protos_info(proto_path);

    let proto_messages = get_proto_list(&proto_files);

    //!!!   this is importent.   !!!

    protoc_rust::run(protoc_rust::Args

        out_dir: proto_path,

        input: &protos,

        includes: &[proto_path],

        customize: Customize

          ..Default::default()

        ,

    ).expect("protoc");

    //now generate factory codes

    generate_factory_file(proto_path, &proto_files);

  然后把build.rs添加到toml里面去

4. 到主工程里面去, 添加对proto工程的依赖

1

2

[dependencies]

proto = version="^0", path="proto"

 

这时候, 就可以在主工程里面使用proto了

1

2

3

4

5

6

7

8

9

10

11

12

extern crate proto;

use proto::factory::*;

use proto::rpc::*;

use local_ipaddress;

fn main()

    let desc = get_descriptor("mypkg.MyType".to_string()).unwrap();

    println!("", desc.full_name());

    let msg = desc.new_instance();

    println!("msg: :?", msg);

  

cargo run:

就可以看到

mypkg.MyType

msg:

这时候就可以拿到MessageDesriptor, 通过这个对象可以new一个instance

仓库在这里https://crates.io/crates/protobuf_message_factory

关键字: MessageFactory, Protobuf, Rust

java示例代码_根据给定的消息类型名称和原始字节获取Java对象的protobuf

java示例代码_根据给定的消息类型名称和原始字节获取Java对象的protobuf 查看详情

protobuf 库在消息实例化时抛出 FatalException

】protobuf库在消息实例化时抛出FatalException【英文标题】:FatalExceptionthrownbyprotobuflibraryoninstantiationofmessage【发布时间】:2018-10-1910:26:22【问题描述】:我正在从源代码编译protobuf3.6.1并链接到一个针对Ubuntu16.04的可执行文件。一旦... 查看详情

对象的创建及其使用(代码片段)

通常情况下,一个类是不能直接使用的,需要根据类创建一个对象,才能使用一般类的使用步骤:导包import包名称.类名称创建对象:类名 对象名= new 类名();使用使用成员变量------->对象名.变量名使用成员方法-------... 查看详情

如何在构建消息之前在 protobuf 中设置重复字段?

】如何在构建消息之前在protobuf中设置重复字段?【英文标题】:Howtosetrepeatedfieldsinprotobufbeforebuildingthemessage?【发布时间】:2015-03-2015:28:47【问题描述】:假设我有一个包含重复字段的消息:MessageFoorepeatedBarbar=1;现在我想将nBar对... 查看详情

java protobuf如何从int创建ByteString

】javaprotobuf如何从int创建ByteString【英文标题】:javaprotobufhowtocreateByteStringfromint【发布时间】:2012-09-0508:19:01【问题描述】:我想在我的项目中使用googleprotobuf。关键是我必须设置非常消息的第一个字节,因为底层代码根据第一... 查看详情

了解事件总线(代码片段)

...个空Vue对象赋值给一个变量2.通过这个对象调用.$emit('消息名','值')发布消息3.使用.$on('消息名',处理函数)用来监听.$off('消息名' 查看详情

rust特征对象(代码片段)

...型方法可以通过&引用或者Box<T>智能指针的方式来创建特征对象。注意dyn不能单独作为特征对象的定义,例如下面的代码编译器会报错,原因是特征对象可以是任意实现了某个特征的类型,编译器在编译期不知道该类型的... 查看详情

google protobuf-js:如何有效地解析我的消息

】googleprotobuf-js:如何有效地解析我的消息【英文标题】:googleprotobuf-js:Howtoparseefficientlymymessages【发布时间】:2017-12-0614:43:04【问题描述】:我正在开发一个Angular5+前端,它使用带有WebSocket的google-protobufJS与后端进行通信。我的.... 查看详情

Protobuf 消息是不是独立于平台

】Protobuf消息是不是独立于平台【英文标题】:AreProtobufmessagesplatformindependentProtobuf消息是否独立于平台【发布时间】:2013-09-0617:10:01【问题描述】:我正在计划一个应用程序,其中服务器端将用C#编写,客户端将使用phonegap创建... 查看详情

流式传输 protoBuf 消息的设计模式

】流式传输protoBuf消息的设计模式【英文标题】:designpatternforstreamingprotoBufmessages【发布时间】:2013-11-1908:47:29【问题描述】:我想将protobuf消息流式传输到文件中。我有一个protobuf消息messagecar...//somefields我的java代码会创建这个... 查看详情

activemq入门实例

  首先了解下jms。  JMS即Java消息服务(JavaMessageService)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。JMS对象模型包含如下几个要素... 查看详情

Rust Trait 对象转换

】RustTrait对象转换【英文标题】:RustTraitobjectconversion【发布时间】:2017-05-2700:35:54【问题描述】:由于此错误的两个实例,以下代码将无法编译:error[E0277]:traitboundSelf:std::marker::Sized不满足我不明白为什么在这种情况下需要Sized... 查看详情

对象的创建及其使用(代码片段)

通常情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用。(仅供参考)步骤导包:也就是指出需要使用的类,在什么位置。import包名称.类名称;对于和当前类属于同一个包的情况下,导包语句可以省略不写... 查看详情

是否可以使用 protobuf 解析非 protobuf 消息?

】是否可以使用protobuf解析非protobuf消息?【英文标题】:Isitpossibletoparsenon-protobufmessagesusingprotobuf?【发布时间】:2013-04-2320:10:01【问题描述】:我正在做一个项目,我们使用协议缓冲区来创建和解析我们的一些消息(protobuf-net)... 查看详情

面向对象

...以包含多个函数,类中定义的这些函数称为方法,对象就是根据模板创建的实例,通过实例对象可以执行类中的方法.类的定义:    class类名:    #定义了一个类      def函数名(self)    # 查看详情

使用 protobuf-net,是不是可以在不分配内存的情况下反序列化消息?

】使用protobuf-net,是不是可以在不分配内存的情况下反序列化消息?【英文标题】:Usingprotobuf-net,isitpossibletodeserializeamessagewithoutallocatingmemory?使用protobuf-net,是否可以在不分配内存的情况下反序列化消息?【发布时间】:2012-01-1... 查看详情

c#如何根据指定变量来实例化对象?

我有一个方法,方法的参数约束了传入的参数必须实现某个接口。我想在这个方法里面从新创建实例化一个以当前参数类型的实例该如何操作classProgramstaticvoidMain(string[]args)staticvoidC(IAa)//我需要在这里从新创建一个a类型的实例inte... 查看详情

对象的创建

  创建一个类,实际上是定义了一种新的复合数据类型。声明该类的一个变量,就是声明该类的对象过程。创建对象包括对象的声明和实例化两步。1.对象的声明  对象的声明主要是声明该对象是哪个类的对象,语法如下:... 查看详情