2 Stimmen

Serialisieren in C# (protobuf-net) , Deserialisieren in C++ (protobuf) : Mehr als 5 Felder in der Klasse

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.

0voto

Marc Gravell Punkte 970173

Ich habe es mit dem Reader in v2 analysiert, und es scheint vollkommen sinnvoll zu sein:

1=5
2=0
3=
4=yo
5=6
6=2 bytes, 68-69
7=how
8=are
9=you
10=sir

Beachten Sie, dass ich das getan habe rein aus den Hexadezimal-Daten (ohne .proto), aber es sollte Ihren Originaldaten sehr ähnlich sein. Vor allem aber scheinen sie intakt zu sein.

Also: Überprüfen Sie als erstes, ob die Binärdatei, die Sie auf der C++-Seite erhalten, genau mit der gesendeten Binärdatei übereinstimmt; dies ist doppelt wichtig, wenn Sie unterwegs irgendwelche Übersetzungen vornehmen (z. B. binary => string - was über base-64 erfolgen sollte).

zweite Sache; wenn das nicht funktioniert, ist es möglich dass es ein Problem in der C++-Implementierung gibt. Es scheint Unwahrscheinlich da dies eines der Haustiere von Google ist, aber nichts ist unmöglich. Wenn die Binärdatei unversehrt ankommt, sich aber immer noch seltsam verhält, kann ich versuchen, mit den C++-Leuten zu sprechen, um zu sehen, ob einer von uns verrückt geworden ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X