在C#(protobuf-net)中序列化,在C ++中反序列化(protobuf):课堂上超过5个字段

时间:2011-06-24 20:44:30

标签: c++ protocol-buffers protobuf-net zeromq

我无法在C ++中反序列化我在C#中序列化的对象,然后使用ZMQ通过网络发送。我相当肯定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类(proto文件):

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()才能发送内部使用的数据。感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我已经通过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 =&gt;字符串 - 应该通过base-64完成),这是非常重要的。

第二件事;如果这不起作用,那么可能在C ++实现中存在问题。似乎不太可能,因为那是谷歌的宠物之一,但没有什么是不可能的。如果二进制文件完好无损,但它仍然表现得很奇怪,我可以尝试与C ++人员交谈,看看我们中的一个人是否已经成为杜鹃。