我正在使用 Google Protobuf 3.0.0。和ZeroMQ来实现服务器和一些客户端之间的连接。所以,我的原型文件看起来像这样:
// message Request{} omitted
message Response{
enum MessageType{
Type1 = 0;
Type2 = 1;
Type3 = 2;
}
enum ConfirmationCode{
OK = 0;
Error1 = 1;
Error2 = 2;
}
MessageType Type = 1;
repeated someField1 field1 = 2;
// ... some code omitted
ConfirmationCode Confirm = 3;
}
如您所见,在 ProtoBuf 3 中不再有
required
或 optional
字段,并且我不使用任何默认值。
现在,我在序列化一些 Protobuf 消息并尝试通过 ZMQ 发送它们时遇到了一些麻烦。 google::protobuf::message_lite::SerializeToString(...)
完成的序列化不会失败,但这个方法和google::protobuf::message_lite::SerializeAsString()
仍然会产生空字符串,所以我认为在序列化之前我的响应中可能没有设置任何字段,因此我引入了类似于以下的方法
void InitResponse(Response& resp)
{
resp.set_confirm(Response_ConfirmationCode_OK);
resp.set_type(Response_MessageType_Type1);
}
确保至少存在一些字段。尽管如此,在调用此方法之前和之后,我的序列化响应的长度为 0。我也尝试使用
google::protobuf::Message::DebugString()
但我认为此方法不会打印存在的每个字段,因为我总是最终打印空字符串。
如果序列化没有失败,为什么我的序列化消息最终会变成空?
https://developers.google.com/protocol-buffers/docs/proto3#default
对于枚举,默认值为第一个定义的枚举值,该值必须为 0。
PB 枚举与“通常”枚举(例如 C(++))的语义动物不同。 PB 并不是应用程序内存的“另一种解释”。如果您确实希望应用程序变量生成非零 PB 缓冲区,请不要使用这些变量的默认值。它适用于所有 PB 数据类型,而不仅仅是枚举。 int=0、float=0.0、bool=false 的 PB 消息也将是零缓冲区。