[英]Serialize in C# (protobuf-net) , Deserialize in C++ (protobuf) : More than 5 fields in class
我在用C#序列化然后使用ZMQ通過網絡發送的C ++中反序列化對象時遇到麻煩。 我相當確定ZMQ部分工作正常,因為C ++服務器應用程序(Linux)成功地從C#(Windows)接收了序列化的消息,並將它們發送回Windows,在此它可以成功地對消息進行反序列化,所以我不認為我在這方面遇到了任何形式的截斷或丟棄的數據包。
但是,當我在Linux服務器上收到消息時,C ++反序列化方法未正確反序列化,它將一些二進制數據拋出到第6個字段中(我可以在MyObject.DebugString()中看到),但其中沒有數據任何其他領域。 但是,這里的奇怪之處在於,我在5個字段中上過一堂課,效果很好。 C ++對其進行了反序列化,並且所有數據均正常運行。 以下是我的代碼的一些花絮。 任何幫助將不勝感激。
C#:
MemoryStream stream = new MemoryStream();
ProtoBuf.Serializer.Serialize<TestType>(stream, (TestType)data);
_publisher.Send(stream.ToArray());
C++:
message_t data;
int64_t recv_more;
size_t recv_more_sz = sizeof(recv_more);
TestType t;
bool isProcessing = true;
while(isProcessing)
{
pSubscriber->recv(&data, 0);
t.ParseFromArray((void*)(data.data()),sizeof(t));
cout<<"Debug: "<<t.DebugString()<<endl;
pSubscriber->getsockopt(ZMQ_RCVMORE, &recv_more, &recv_more_sz);
isProcessing = recv_more;
}
輸出看起來像這樣:
Debug: f: "4\000\000\000\000\000\"
我在復制和粘貼時遇到了麻煩,但是輸出繼續進行,大概需要3或4行。
這是我的TestType類(原型文件):
package Base_Types;
enum Enumr {
Dog = 0;
Cat = 1;
Fish = 2;
}
message TestType {
required double a = 1;
required Enumr b = 2;
required string c = 3;
required string d = 4;
required double e = 5;
required bytes f = 6;
required string g = 7;
required string h = 8;
required string i = 9;
required string j = 10;
}
字段“ f”被列為字節,因為當它是一個字符串之前,它曾向我發出有關UTF-8編碼的警告,但是,當此類僅使用5個字段(枚舉是其中之一)時,它沒有給出我那個錯誤。 幾乎就像是在不進行反序列化一樣,它是將整個類的二進制文件扔到字段“ f”(字段6)中。
解決方案:最終出現了一個問題,即在將內存發送到線程套接字之前,沒有將其復制。 當發布者退回時,它正在打包數據並更改路由器收到的內容。 為了發出要在內部使用的數據,C ++端需要有一個memcpy()。 感謝您的所有幫助。
我已經通過v2中的閱讀器對其進行了解析,這似乎很有意義:
1=5
2=0
3=
4=yo
5=6
6=2 bytes, 68-69
7=how
8=are
9=you
10=sir
請注意,我只是從十六進制數據中完成了此操作(不使用.proto),但是它應該接近原始數據。 但最值得注意的是,它似乎完好無損。
所以:第一件事要做; 檢查在C ++端獲取的二進制文件與您發送的二進制文件完全相同; 如果您在進行翻譯(例如,binary => string,應通過base-64進行翻譯),則這一點就非常重要。
第二件事 如果這不起作用,則C ++實現中可能存在問題。 由於這是Google的寵兒之一,因此似乎不太可能 ,但是沒有什么是不可能的。 如果二進制文件完整無缺,但仍然表現不正常,我可以嘗試與C ++人員交流,看看我們中的一個人是否布谷鳥。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.