为什么我的Protobuf类可以解析由其他Protobuf类串联的字符串
Why my Protobuf class can parse a string serialized by an other Protobuf class
我试图知道我在TCP插座中获得的软件包,因此我使用ProtoBuf。但是当我SerializeToString
我的第一个Protobuf类时,其他Protobuf类的ParseFromString
返回true。
这两个类别是不同的
这是我的.proto
syntax = "proto3";
package protobuf;
message Message
{
string content = 1;
}
message Player
{
int32 id = 1;
string name = 2;
}
这是我的C 代码
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
为什么?
我建议解决多个有效载荷问题的建议:
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
歧视的联合枚举以查看如何解释数据。然后分别访问foo
或bar
。
这种方法清晰,明显,并且很容易且有效地扩展到其他消息类型中。可以用许多编程语言使用switch
实施测试。这种样式在某些环境中的多态性也很好地效果很好 - 例如,在c#的Protobuf -net中,可以通过以下方式序列化/进行序列化:
[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;}
}
编辑:那么,现在,它是最好的方法吗?
syntax = "proto3";
message Header
{
oneof payload
{
Message message = 1;
Player player = 2;
}
}
message Message
{
string content = 1;
}
message Player
{
int32 id = 1;
string name = 2;
}
写作时:
void SocketManager::sendData(Player& player)
{
Header header;
header.set_allocated_player(&player);
write(header);
}
void SocketManager::sendData(Message& message)
{
Header header;
header.set_allocated_message(&message);
write(header);
}
// etc... for each kind of message
我阅读时:
void read(const std::string& data)
{
protobuf::Header header;
header.ParseFromString(data);
switch (header.payload_case())
{
case protobuf::Header::kMessage:
emit messageProtoReceived(header.message());
break;
case protobuf::Header::kPlayer:
emit playerProtoReceived(header.player());
break;
case protobuf::Header::PAYLOAD_NOT_SET:
qDebug() << "Error, the payload isn't set, please create a header with a payload";
break;
}
}
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 在其他文件中创建类时在 c++ 项目中不起作用
- 类与私有变量的其他类之间的线程安全性
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- GlobalAlloc而不是其他分配方法
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 断言中的Fold表达式在某些计算机上编译,但在其他计算机上不编译
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 结构和双指针隐藏在其他结构中,多层混淆
- UE4在OnComponentBeginOverlap上铸造其他actor
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 当我在其中一个线程执行中(在activemq-cpp中)捕获到特定值时,我如何终止/停止所有其他线程
- MESI协议和std::atomic-它是否确保所有写入立即对其他线程可见?
- 保留对其他类的成员函数的引用
- 为什么我的Protobuf类可以解析由其他Protobuf类串联的字符串
- 如何为包含其他 protobuf 的 protobuf 文件编写文本