Ich habe Probleme beim Deserialisieren eines Objekts in C++, das ich in C# serialisiert und dann mit ZMQ über das Netzwerk gesendet habe. Ich bin mir ziemlich sicher, dass der ZMQ-Teil korrekt funktioniert, da die C++-Serveranwendung (Linux) die serialisierten Nachrichten von C# (Windows) erfolgreich empfängt und sie zurück an Windows sendet, wo die Nachricht erfolgreich deserialisiert werden kann. Ich glaube also nicht, dass ich in dieser Hinsicht irgendeine Art von abgeschnittenen oder verlorenen Paketen erlebe.
Wenn ich jedoch die Nachricht auf dem Linux-Server empfange, deserialisiert die C++-Methode nicht korrekt, sondern wirft einen Haufen Binärdaten in das sechste Feld (ich kann dies in MyObject.DebugString() sehen), aber keine Daten in anderen Feldern. Das Seltsame daran ist jedoch, dass eine Klasse mit 5 Feldern völlig problemlos funktioniert. C++ deserialisiert sie korrekt und alle Daten funktionieren einwandfrei. Unten sind ein paar Leckerbissen meines Codes. Für jede Hilfe wäre ich sehr dankbar.
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;
}
Die Ausgabe sieht wie folgt aus:
Debug: f: "4\000\000\000\000\000\"
Ich habe Probleme mit dem Kopieren und Einfügen, aber die Ausgabe geht so weiter, wahrscheinlich für 3 oder 4 Zeilen davon.
Dies ist meine TestType-Klasse (Proto-Datei):
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;
}
Feld "f" ist als Bytes aufgeführt, weil, wenn es eine Zeichenfolge war, bevor es gab mir eine Warnung über UTF-8-Codierung, jedoch, wenn diese Klasse mit nur 5 Felder (die Enum war einer von ihnen) gearbeitet, es gab mir nicht diesen Fehler. Es ist fast wie statt der Deserialisierung, es wirft die binäre für die gesamte Klasse in Feld "f" (Feld 6).
Lösung: Am Ende gab es ein Problem, bei dem der Speicher nicht kopiert wurde, bevor er an einen Thread-Socket gesendet wurde. Wenn der Publisher zurück sendete, verpackte er die Daten und änderte, was der Router empfing. Es muss ein memcpy() auf der C++ Seite geben, um die Daten zur internen Verwendung zu senden. Vielen Dank für all die Hilfe.