我在反序列化 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() 以便发送要在内部使用的数据。感谢所有的帮助。