У меня возникли проблемы с десериализацией объекта на C++, который я сериализовал на C#, а затем отправил по сети с помощью ZMQ. Я совершенно уверен, что часть ZMQ работает правильно, потому что серверное приложение C++ (Linux) успешно получает сериализованные сообщения от C# (Windows) и отправляет их обратно в Windows, где оно может успешно десериализовать сообщение, поэтому я не думаю, что я Я испытываю какие-либо усеченные или отброшенные пакеты в этом отношении.
Однако, когда я получаю сообщение на сервере Linux, метод десериализации C++ неправильно десериализует, он выбрасывает какую-то кучу двоичных данных в 6-е поле (я вижу это в MyObject.DebugString()), но нет данных в любые другие поля. Однако странная часть здесь заключается в том, что класс, который у меня был с 5 полями, работает отлично. С++ правильно десериализует его, и все данные работают правильно. Ниже приведены несколько лакомых кусочков моего кода. Любая помощь будет принята с благодарностью.
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(), чтобы отправлять данные для внутреннего использования. Спасибо за помощь.