简体   繁体   English

在C#(protobuf-net)中序列化,在C ++(protobuf)中反序列化:类中的5个以上字段

[英]Serialize in C# (protobuf-net) , Deserialize in C++ (protobuf) : More than 5 fields in class

I'm having trouble deserializing an object in C++ that I had serialized in C# and then sent over the network with ZMQ. 我在用C#序列化然后使用ZMQ通过网络发送的C ++中反序列化对象时遇到麻烦。 I'm fairly certain the ZMQ part is working correctly because the C++ server application (Linux) successfully receives the serialized messages from C# (Windows) and sends them back to Windows where it can successfully deserialize the message, so I don't think I'm experiencing any sort of truncated or dropped packets in that regard. 我相当确定ZMQ部分工作正常,因为C ++服务器应用程序(Linux)成功地从C#(Windows)接收了序列化的消息,并将它们发送回Windows,在此它可以成功地对消息进行反序列化,所以我不认为我在这方面遇到了任何形式的截断或丢弃的数据包。

However, when I receive the message on the Linux server, the C++ deserialize method does not correctly deserialize, it throws some a bunch of binary data into the 6th field (I can see this in MyObject.DebugString()), but no data in any other fields. 但是,当我在Linux服务器上收到消息时,C ++反序列化方法未正确反序列化,它将一些二进制数据抛出到第6个字段中(我可以在MyObject.DebugString()中看到),但其中没有数据任何其他领域。 The strange part here, however, is that a class I had with 5 fields works perfectly fine. 但是,这里的奇怪之处在于,我在5个字段中上过一堂课,效果很好。 C++ deserializes it correctly and all of the data is working properly. C ++对其进行了反序列化,并且所有数据均正常运行。 Below are a few tidbits of my code. 以下是我的代码的一些花絮。 Any help would be greatly appreciated. 任何帮助将不胜感激。

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;
    }

The output looks like this: 输出看起来像这样:

Debug: f: "4\000\000\000\000\000\"

I'm having trouble copy and pasting, but the output continues like that for probably 3 or 4 lines worth of that. 我在复制和粘贴时遇到了麻烦,但是输出继续进行,大概需要3或4行。

This is my TestType class (proto file): 这是我的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;
}

Field "f" is listed as bytes because when it was a string before it was giving me a warning about UTF-8 encoding, however, when this class worked with only 5 fields (the enum was one of them), it did not give me that error. 字段“ f”被列为字节,因为当它是一个字符串之前,它曾向我发出有关UTF-8编码的警告,但是,当此类仅使用5个字段(枚举是其中之一)时,它没有给出我那个错误。 It's almost like instead of deserializing, it's throwing the binary for the entire class into field "f" (field 6). 几乎就像是在不进行反序列化一样,它是将整个类的二进制文件扔到字段“ f”(字段6)中。

Solution: There ended up being an issue where the memory wasn't being copied before it sent to a thread socket. 解决方案:最终出现了一个问题,即在将内存发送到线程套接字之前,没有将其复制。 When the publisher sent back out, it was packaging the data and changing what the router received. 当发布者退回时,它正在打包数据并更改路由器收到的内容。 There needs to be a memcpy() on the C++ side in order to send out the data to be used internally. 为了发出要在内部使用的数据,C ++端需要有一个memcpy()。 Thanks for all of the help. 感谢您的所有帮助。

I've parsed it through the reader in v2, and it seems to make perfect sense: 我已经通过v2中的阅读器对其进行了解析,这似乎很有意义:

1=5
2=0
3=
4=yo
5=6
6=2 bytes, 68-69
7=how
8=are
9=you
10=sir

Note that I've done that purely from the hex data (not using the .proto), but it should be close to your original data. 请注意,我只是从十六进制数据中完成了此操作(不使用.proto),但是它应该接近原始数据。 But most notably, it seems intact. 但最值得注意的是,它似乎完好无损。

So: first thing to do; 所以:第一件事要做; check that the binary you get at the C++ side is exactly the same as the binary you sent; 检查在C ++端获取的二进制文件与您发送的二进制文件完全相同; this is doubly important if you are doing any translations along the way (binary => string, for example - which should be done via base-64). 如果您在进行翻译(例如,binary => string,应通过base-64进行翻译),则这一点就非常重要。

second thing; 第二件事 if that doesn't work, it is possible that there is a problem in the C++ implementation. 如果这不起作用,则C ++实现中可能存在问题。 It seems unlikely since that is one of google's pets, but nothing is impossible. 由于这是Google的宠儿之一,因此似乎不太可能 ,但是没有什么是不可能的。 If the binary comes across intact, but it still behaves oddly, I can try speaking to the C++ folks, to see if one of us has gone cuckoo. 如果二进制文件完整无缺,但仍然表现不正常,我可以尝试与C ++人员交流,看看我们中的一个人是否布谷鸟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM