Fan*_*Fox 6 c# protocol-buffers
在下面的代码中,我想在 C# 中使用预定义的 protobuf 消息。我发现我能够编写并使用该方法来获取已创建的方法并制作byte[]:
ContainerMessage containerMessage = new ContainerMessage();
containerMessage.Type = CommandType.Connect;
containerMessage.Connect = new Connect();
containerMessage.Connect.ClientName = "TemporaryClientName";
byte[] stream = new byte[containerMessage.CalculateSize()];
using (Google.Protobuf.CodedOutputStream outstream = new Google.Protobuf.CodedOutputStream(stream))
{
containerMessage.WriteTo(outstream);
}
Run Code Online (Sandbox Code Playgroud)
这按预期工作,我可以检查消息,并且值与预期的一样byte[]。但是,如果我尝试反序列化,即使是byte[]我刚刚创建的这个简单的:
using (Google.Protobuf.CodedInputStream instream = new Google.Protobuf.CodedInputStream(stream))
{
instream.ReadMessage(containerMessage);
}
Run Code Online (Sandbox Code Playgroud)
它失败了:
Google.Protobuf.dll 中发生“Google.Protobuf.InvalidProtocolBufferException”类型的未处理异常
附加信息:协议消息包含无效标签(零)。
这是从byte[]正确的 protobuf 反序列化的方式吗?
Protobuf 的定义是:
message ContainerMessage {
CommandType type = 1;
bool commandSuccess = 2;
oneof message {
Connect connect = 3;
}
}
enum CommandType {
START = 0;
CONNECT = 2;
}
message Connect {
string ClientName = 1;
uint32 PushPullPort = 2;
}
Run Code Online (Sandbox Code Playgroud)
CS文件是用命令行生成的:
protoc.exe -I=%CD% --csharp_out=..\GeneratedCsMessaging\ Connect.proto
Run Code Online (Sandbox Code Playgroud)
和主要供编译的原型类使用CodedOutputStream。CodedOutputStream 的 API声明了这一点,并提到如果您希望手动编写的代码调用这两个类中的任何一个,则需要在每个值之前使用它们的方法。CodedInputStreamWriteTag
但是,由于您想使用 Google Protobuf 进行序列化和解析任何 System.IO.Stream 都会按照预期完成这项工作。C# Protocol Buffer 基础知识的解析和序列化部分对此进行了详细记录和描述。在 Google Protobuf 的 Github 中可以找到的示例对于快速掌握 Google Protobuf 的窍门非常有帮助。在那里您可以看到 a用于序列化对象,而该方法可用于从序列化数据中解析对象。MemoryStreamParse.ParseFrom
正如您在问题评论中提到的,using Google.Protobuf;这是使用 Google Protobuf 功能的重要组成部分。
编辑:您的案例中的示例用法可能如下所示
byte[] serializedBytes;
ContainerMessage containerMessage = new ContainerMessage()
{
Connect = new Connect()
{
ClientName = "TemporaryClientName",
},
Type = CommandType.Connect,
};
using( MemoryStream stream = new MemoryStream())
{
containerMessage.WriteTo(stream);
serializedBytes = stream.ToArray();
}
ContainerMessage parsedCopy = ContainerMessage.Parser.ParseFrom(serializedBytes);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10923 次 |
| 最近记录: |