[英]Protobuf-net is incompatible with official google Protobuf for C++ (message encoding)
.NET中有一些(很多)類。 我們使用protobuf-net對其進行了標記,並通過google原始庫為C ++代碼端生成了.proto包裝器。
因此,我收到一條消息(某些EventBase類上的C ++ DebugString()(在.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能夠解碼相同內容)?
或者至少如何使原始的Google protobuf編碼與.NET protobuf相同?
對於那些真正感興趣並希望通過簡化示例進入壓縮包的用戶(包括適用於C ++和C#代碼的VS 2010解決方案)
編輯; 該問題應在r616及更高版本中修復。
我終於有機會研究一下(為延遲而道歉,但社交季節性假期需求有所干預)。 我了解現在發生了什么。
基本上,數據在理論上是相同的; 這實際上歸結為現場排序。 從技術上講,字段通常按升序編寫,但可以按任何順序期望。 關於protobuf網; 對於不涉及繼承的類型,無論順序如何,它都可以正常工作。 protobuf規范沒有定義繼承,因此protobuf-net在規范的基礎上(由於不斷的需求) 增加了對該繼承的支持。 作為一種實施的功能時,它首先寫入(即字段15,子類型,則提前寫入字段10)的子類的信息。 當前,在反序列化期間,它也首先需要子類型信息。 這幾乎對任何人都沒有影響,因為既然protobuf-net是唯一這樣使用繼承的實現,那么繼承功能的使用通常僅在protobuf-net到protobuf-net的使用中才能看到。
就您而言,您正在使用.proto與CPP互操作; 這意味着CPP代碼將能夠使用protobuf-net數據,但是它可能會有類型轉換異常(反之亦然)(基本上,它在獲取第一個數據字段時便開始構造具體類型)。
盡管很少有問題,但這是需要解決的問題。 我可以嘗試今天晚些時候或明天看看。
選項:
EventBase
只編寫帶有EventCharacterMoved
數據的EventBase
,然后進行序列化; 現在在一個單獨的模型中, 僅使用TreeFloat
數據編寫一個EventBase
並進行序列化; 這將模擬按要求的順序編寫它們(protobuf流是可附加的)-不太漂亮 這看起來與http://code.google.com/p/protobuf-net/issues/detail?id=299和http://code.google.com/p/protobuf-net/issues中指出的問題非常相似/ detail?id = 331 ,據稱由http://code.google.com/p/protobuf-net/source/detail?r=595修復。
您使用的.NET protobuf版本是否足夠新,可以合並該修復程序?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.