【问题标题】:Serialize in C# (protobuf-net) , Deserialize in C++ (protobuf) : More than 5 fields in class在 C# (protobuf-net) 中序列化,在 C++ (protobuf) 中反序列化:类中超过 5 个字段
【发布时间】:2012-03-08 00:10:21
【问题描述】:

我在反序列化 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 类(原型文件):

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() 以便发送要在内部使用的数据。感谢大家的帮助。

【问题讨论】:

  • Marc Gravell..你在哪里?
  • 有趣。几个问题 - 在 c# 中,它是否成功 DeepClone()?什么版本的 protobuf-net(我可以调查一下)?
  • @Cyber​​nate 在这里,谢谢
  • 我还没试过 DeepClone(),一会儿试试。 protobuf-net.dll 版本是 protobuf-net r282 的 CF35。
  • 它确实成功了,事实上,DeepClone() 成功

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


【解决方案1】:

我已经通过 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++ 端获得的二进制文件是否与您发送的二进制文件完全相同;如果您在此过程中进行任何翻译(例如,二进制 => 字符串 - 应该通过 base-64 完成),这一点就非常重要。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多