rust下根據protobuf的消息名創建對象實例


在C++里面, 我們可以根據一個消息的名稱, 動態的創建一個實例

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文件

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工程的依賴

[dependencies]
proto = {version="^0", path="proto"}

 

這時候, 就可以在主工程里面使用proto了

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM