Protobuf-net 上使用嵌套数据反序列化的无效线类型异常(C++ 到 C#)

Invalid Wire Type Exception on Protobuf-net Deserialize with Nested Data (C++ to C#)

我得到了一个 C++ 应用程序(一个构建的可执行文件和源代码,但现在还没有构建),它使用生成的原型 类 来发送 protobuf 消息。我采用了用于生成其 类 的相同 .proto 文件,并在 C# 应用程序中生成了关联的 类。目的是能够在 C# 端使用 protobuf-net 在这些应用程序之间接收和发送消息。请注意,两者都使用 proto2 格式。

只有简单类型(例如int)成员的消息可以成功序列化和反序列化。但是,将具有嵌套消息类型的消息反序列化到我的 C# 应用程序中似乎存在问题,例如

message Outer {
    optional Inner = 1;
}

message Inner {
    optional float f = 1;
}

接收到的 "Outer" 类型的消息将无法在 C# 中通过以下方式反序列化:

Serializer.Deserialize<T>(new MemoryStream(msg)); // msg is a byte[]

给出 "Invalid Wire Type Exception." 我遵循了 link here,但在查看了这些答案后,我没有发现任何与我的情况相关的立即明显的内容。我 95% 确定生成的源和目标 类 相同,数据没有损坏,并且我正在反序列化为正确的类型。

我能否正确反序列化此类嵌套类型? C++ 应用程序与使用 protobuf-net 的 C# 应用程序中 类 的生成方式(及其序列化方式)是否存在兼容性问题?

Here 是一个示例项目(在 VS 2019 中为 .NET Core 3.1 制作),它将重现该问题。

我的传入数据有大约 50 个额外字节 "stuff" 我没有预料到(即不是消息 header),它不符合定义的消息格式,所以数据本质上是腐败的。很难通过查看字节流来判断这一点;泄露的是我在 C# 端序列化的消息长度与我从传入消息的 wireshark 中读取的字节相比的差异。然后我查看了这些字节并找到了与我的序列化消息等效的字节英寸

为什么传入消息中有额外的 "stuff" 是另一回事,但这是一个实现细节,所以我会认为这个问题已关闭。

如果它能帮助处于类似情况的任何人,我做了一个小测试循环以继续尝试反序列化 byte-by-byte 直到它工作(可以改进但现在工作):

var rawBytes = msg.GetBytes(); // The raw incoming message
bool success = false;
OuterMsgType outer;
while (!success)
{
    try
    {
        rawBytes = rawBytes.Skip(1).ToArray();
        outer = ProtoBuf.Serializer.Deserialize<OuterMsgType>(new MemoryStream(rawBytes));
        if (outer?.InnerMsg != null)
             success = true;
    }
    catch (Exception e)
    {
        // Wire type exception: Ignore it, don't care
    }
}