我们在 .NET 中有一些(很多)类。我们使用protobuf-net对其进行标记,并通过google original library为 C++ 代码端生成 .proto 包装器。
所以我有一条消息(C++ DebugString() 在一些 EventBase 类上(在 .NET 中EventCharacterMoved
继承EventBase
,而在 C++ 中我只是写入可选属性)):
UserId: -2792
EventCharacterMoved {
Coordinates {
Position {
X: 196.41913
Y: 130
Z: 213
}
Rotation {
X: 207
Y: 130
Z: 213
}
}
OldCoordinates {
Position {
X: 196.41913
Y: 130
Z: 213
}
Rotation {
X: 207
Y: 130
Z: 213
}
}
}
(来自这样的 .proto 文件)
message Coordinates {
optional TreeFloat Position = 1;
optional TreeFloat Rotation = 2;
}
message EventBase {
optional int32 UserId = 10 [default = 0];
// the following represent sub-types; at most 1 should have a value
optional EventCharacterMoved EventCharacterMoved = 15;
}
message EventCharacterMoved {
optional Coordinates Coordinates = 100;
optional Coordinates OldCoordinates = 101;
}
message TreeFloat {
optional float X = 1 [default = 0];
optional float Y = 2 [default = 0];
optional float Z = 3 [default = 0];
}
在 C++ 中,我发送这个,我们从 .NET 发送相同的消息内容。
C++ 代码可以解析 C++ 编码的消息以及 .NET 编码的消息。.NET 代码只能解析 .NET 消息。
通过网络,我们得到 87 个字节(与.Net 文件和C++ 文件大小相同),但内容不同:
如您所见,它相似但不一样。由于这种差异,CPP 代码可以读取 .NET C# 消息,而 .NET 无法读取 CPP 消息。
在反序列化的代码中,我们得到:
TestProto.exe 中发生了“System.InvalidCastException”类型的未处理异常
附加信息:无法将“TestProto.EventBase”类型的对象转换为“TestProto.EventCharacterMoved”类型。
在如下代码中:
using (var inputStream = File.Open(@"./cpp_in.bin", FileMode.Open, FileAccess.Read)) {
var ecm = Serializer.Deserialize<EventCharacterMoved>(inputStream);
}
让我们看一下(如jpa在他的评论中提到的)protoc --decode_raw
选项:
这可能与我的 CPP 包装器使用最新的 google protobuf 版本有关,而 protobuf-net 可能使用一些较旧的编码格式或类似的东西......
所以我想知道如何让 .NET protobuf 读取 C++ 消息(让 tham 能够解码相同的东西)?
或者至少如何使原始谷歌 protobuf 以与 .NET protobuf 相同的方式编码?
对于那些真正感兴趣并希望通过简化示例进入压缩包的人(包括 C++ 和 C# 代码的 VS 2010 解决方案)