【问题标题】:Rust protobuf serialization is all messed upRust protobuf 序列化都搞砸了
【发布时间】:2019-03-08 05:02:09
【问题描述】:

我正在使用rust-protobuf 版本2.4 我有以下代码

let mut msg = vec![];
let mut str = protobuf::CodedOutputStream::vec(&mut msg);
let mut rmsg = user_manager::user::user_data::new();
rmsg.set_id("1234".into());
rmsg.set_nick("test".into());
str.write_message(1, &rmsg).unwrap();
str.flush().unwrap();
println!("{:?}", msg);
let test: register_msg = protobuf::parse_from_bytes(&msg[..]).unwrap();
println!("serialized: {:?}\noriginal: {:?}", test, rmsg);

相关的proto描述如下

message user_data{
    string id           = 1; //required
    string nick         = 2;
    string theme        = 3;
    string admin_id     = 4;
    string lang         = 5;
    double credit       = 6; //required
    double bonus_credit = 7; //required
};

结果我得到的都是一团糟

首先,如果我序列化整个消息,为什么我需要输入一个数字?这是一个非常奇怪的设计。

其次,您可能在 proto 文件中看到的第一个字段是 id,但序列化的输出显示 protobuf 包将所有内容序列化为第二个字段的 nick 字段。

我是不是做错了什么,或者这可能是库中的错误?

更新 1:

我已将write_msg 更改为write_to_bytes 这就是我的代码现在的样子。

let mut rmsg = user_manager::user::user_data::new();
rmsg.set_id("1234".into());
rmsg.set_nick("test".into());
let msg = rmsg.write_to_bytes().unwrap();
println!("{:?}", msg);
println!("{:?}", &msg[..]);
let test: register_msg = protobuf::parse_from_bytes(&msg).unwrap();
println!("serialized: {:?}\noriginal: {:?}", test, rmsg);

而且,输出仍然一团糟。

【问题讨论】:

  • write_message的描述,只写了一个字段。试试rmsg.write_to(&mut str),我只是猜测这可能会根据文档起作用。
  • 为什么你认为是 Nick 字段而不是 Id 是索引之一仍然是一个谜:)
  • @JayDepp btw write_to 不存在
  • 你有 Message trait 的作用域吗? Here's the method.
  • 我现在包含了,但输出保持不变 write_to 和 write_message 都表现不正确

标签: rust protocol-buffers grpc


【解决方案1】:

您可以使用Message::write_to_bytes 序列化可以使用parse_from_bytes 解析的消息。

另外,请确保您反序列化的类型与您序列化的类型相同。

这是一个可以正常工作的示例程序:

mod protos;
use protobuf::Message;
use protos::user_data::user_data;

fn main() {
    let mut rmsg = user_data::new();
    rmsg.set_id("1234".into());
    rmsg.set_nick("test".into());

    let msg = rmsg.write_to_bytes().unwrap();
    println!("{:?}", msg);

    let test: user_data = protobuf::parse_from_bytes(&msg).unwrap();
    println!("serialized: {:?}\noriginal: {:?}", test, rmsg);
}

【讨论】:

  • 我仍然得到完全相同的结果 id 被用作 nick 并且 id 在反序列化的结构中不存在。
  • 您的代码仍然使用user_data 作为序列化值,register_msg 作为反序列化值。像这样使用两种不同的类型是行不通的。对两个值使用相同的类型。
  • 哦,真是个愚蠢的错误。我怎么没看到。感谢您的帮助
【解决方案2】:

这一行:

str.write_message(1, &rmsg).unwrap();

将消息rmsg 写为带有字段ID 1 的子消息。因此,这些字段最终嵌套更深一层,就好像您的 .proto 是:

message wrappermsg {
    user_data msg = 1;
}

正确的方法是:

rmsg.write_to(&mut str);

【讨论】:

  • 不幸的是,它没有改变任何结果结果仍然是错误@jpa
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-10
相关资源
最近更新 更多