Rust中Protobuf使用详解
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>工具与环境</li><li>项目中使用</li><ul class="second_class_ul"><li>配置Cargo.toml</li><li>proto文件</li><li>build脚本</li><li>使用proto</li></ul></ul></div><p>Protobuf(Protocol Buffers)是 Google 推出的高效序列化协议;Rust中,prost 是最主流的 Protobuf 实现,提供了编译期代码生成和运行时序列化/反序列化能力。</p><p class="maodian"></p><h2>工具与环境</h2>
<p>必备工具:</p>
<ul><li>protoc:Protobuf 官方编译器(负责解析 <code>.proto</code> 文件)</li><li>prost:Rust 的 Protobuf 运行时库(提供序列化 / 反序列化逻辑)</li><li>prost-build:Rust 的 Protobuf 编译工具(集成 <code>protoc</code>,生成 Rust 代码)</li></ul>
<p>windows下protoc安装(winget方式):</p>
<ol><li><code>winget search protoc</code></li><li><code>winget install Google.Protobuf</code></li><li><code>protoc --version</code>:# 输出 libprotoc 33.0 或更高版本即可</li></ol>
<p class="maodian"></p><h2>项目中使用</h2>
<p class="maodian"></p><h3>配置Cargo.toml</h3>
<p>添加prost与prost-build的依赖,</p>
<div class="jb51code"><pre class="brush:plain;">
prost = "0.14.1"
prost-build = "0.14.1"</pre></div>
<p class="maodian"></p><h3>proto文件</h3>
<p>在项目中添加<code>proto/hello.proto</code>文件:</p>
<div class="jb51code"><pre class="brush:plain;">syntax = "proto3";
package hello;
message MyMessage {
string name = 1;
int32 id = 2;
}</pre></div>
<p class="maodian"></p><h3>build脚本</h3>
<p>在项目根目录添加build.rs用于把proto文件编译为rs文件:</p>
<ul><li>out_dir:设定编译rs文件存放位置(如"src/pb"下);</li><li>compile_protos:编译<ul><li>第一个参数为要编译proto文件(包含相对目录);可以指定多个proto文件</li><li>第二个参数proto所在路径</li></ul></li></ul>
<div class="jb51code"><pre class="brush:plain;">use prost_build;
fn main() {
println!("cargo:rerun-if-changed=hello.proto");
// try create the output folder
std::fs::create_dir_all("src/pb").expect("Failed to create output directory");
// compile the proto file
prost_build::Config::new()
.out_dir("src/pb")
.compile_protos(&["proto/hello.proto"], &["proto/"])
.expect("Failed to compile proto files");
}</pre></div>
<p>build成功后,会在src/pb下创建hello.rs(与proto文件中的package名称相同)文件。</p>
<p class="maodian"></p><h3>使用proto</h3>
<p>生成rs文件后,即可使用:</p>
<ul><li>通过include!宏,直接包含对应rs文件</li><li>通过use引入<ul><li>在pb下创建mod.rs,并添加<code>pub mod hello;</code></li><li>在main中引入:<code>mod pb; use pb::hello::MyMessage;</code></li></ul></li></ul>
<div class="jb51code"><pre class="brush:plain;">// include!("pb/hello.rs");
mod pb;
use pb::hello::MyMessage;
use prost::Message;
fn main() {
let msg = MyMessage {
name: "Protobuff example".to_string(),
id: 123,
};
let encoded = msg.encode_to_vec();
println!("Encoded Msg: {:?}", encoded);
let decoded = MyMessage::decode(&encoded[..]).unwrap();
println!("Decoded Msg: {:?}", decoded);
}</pre></div>
<p>到此这篇关于Rust中Protobuf使用简介的文章就介绍到这了,更多相关Rust Protobuf使用内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
<div class="art_xg">
<b>您可能感兴趣的文章:</b><ul><li>rust 中生成与使用protobuf的方法</li></ul>
</div>
</div>
<!--endmain--> 看到这么详细的Rust+Protobuf教程必须来顶一下!干货满满,讲解得非常清晰明了~
之前一直想学在Rust里用Protobuf,但是百度搜到的教程都写得糊里糊涂的,看得云里雾里。这篇帖子从环境配置到实际使用一步一步写得非常详细,照着操作一遍就能跑通了,给作者点个赞!已收藏
特别是build.rs的部分,之前一直搞不懂out_dir和compile_protos的参数怎么写,这回终于搞明白了原来是这么回事。感谢分享!
有个小问题想请教一下:
如果项目比较大的话,每个proto文件都手动写build.rs感觉有点麻烦,请问有没有更优雅的写法?比如自动扫描某个目录下的所有proto文件然后批量编译?
另外想问一下,如果我想在编译期生成proto代码而不是像这样在build时生成,有没有办法实现?看到有些项目直接把生成的.rs文件提交到仓库里,这种方式有什么优缺点吗?
最后再次感谢楼主的无私分享!源码公社有您更精彩! :D
返回源码公社
页:
[1]