为什么我的 Protobuf 类可以解析由其他 Protobuf 类序列化的字符串 [英] Why my Protobuf class can parse a string serialized by an other Protobuf class

查看:53
本文介绍了为什么我的 Protobuf 类可以解析由其他 Protobuf 类序列化的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图知道我在我的 tcp 套接字中得到了什么包,所以我使用了 protobuf.但是当我 SerializeToString 我的第一个 protobuf 类时,另一个 protobuf 类的 ParseFromString 方法返回 true.

I tried to know what package I got in my tcp socket, so I use protobuf. But when I SerializeToString my first protobuf class, the ParseFromString method of an other protobuf class returns true.

两个类是不同的

这是我的 .proto

syntax = "proto3";

package protobuf;
message Message
{
    string content = 1;
}
message Player
{
    int32 id = 1;
    string name = 2;
}

这是我的 C++ 代码

Here is my c++ code

auto messageProto = new protobuf::Message;
messageProto->set_content("Hello");

std::string data;
messageProto->SerializeToString(&data);

protobuf::Player player;
if (player.ParseFromString(data))
{
    qDebug() << "parse player";
}

protobuf::Message message2;
if (message2.ParseFromString(data))
{
    qDebug() << "parse message";
}

输出:

parse player
parse message

为什么?

推荐答案

我推荐的多个不同payload的解决方案:

My recommended solution to the problem of multiple different payloads:

syntax = "proto3";

package protobuf;
message RenameMe // the outer payload wrapper
{
  oneof payload
  {
    Foo foo = 1;
    Bar bar = 2;
  }
}
message Foo // one type of content
{
    string content = 1;
}
message Bar // another type of content
{
    int32 id = 1;
    string name = 2;
}

现在您可以将所有内容反序列化为 RenameMe(命名很难!)并检查 payload 区分联合枚举以了解您应该如何解释数据.然后分别访问 foobar.

Now you can just deserialize everything as a RenameMe (naming is hard!) and check the payload discriminated union enum to see how you should interpret the data. Then just access foo or bar respectively.

这种方法清晰、显而易见,并且可以轻松有效地扩展到其他消息类型.在许多编程语言中,可以使用 switch 来实现测试.这种风格也适用于某些环境中的多态性 - 例如,在 C# 中,protobuf-net 可以通过以下方式进行序列化/反序列化:

This approach is clear, obvious, and readily and effectively extensible into additional message types. The testing can be implemented with switch in many programming languages. This style also works well with polymorphism in some environments - for example, in C# with protobuf-net that could be serialized/deserialized with:

[ProtoContract, ProtoInclude(1, typeof(Foo)), ProtoInclude(2, typeof(Bar))]
abstract class RenameMe {}

[ProtoContract]
class Foo : RenameMe {
  [ProtoMember(1)] public string Content {get;set;}
}

[ProtoContract]
class Bar : RenameMe {
  [ProtoMember(1)] public int Id {get;set;}
  [ProtoMember(2)] public string Name {get;set;}
}

这篇关于为什么我的 Protobuf 类可以解析由其他 Protobuf 类序列化的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆