Wir hatten einige (viele) Klassen in .NET. Wir haben protobuf-net verwendet, um sie zu markieren und .proto-Wrapper für die C ++ - Codeseite über Google Original-Bibliothek .
Also habe ich eine Nachricht (C ++ DebugString () in einer EventBase-Klasse (in .NET EventCharacterMoved
erbt EventBase
, während ich in C ++ nur in die optionale Eigenschaft schreibe)):
(Aus einer solchen .proto-Datei)
%Vor%In C ++ sende ich das und wir senden den gleichen Nachrichteninhalt von .NET.
Der C ++ - Code kann C ++ - codierte Nachrichten sowie .NET-codierte Nachrichten analysieren. Der .NET-Code kann die .NET-Nachricht nur analysieren.
Über den Draht werden 87 Bytes geflogen (dieselbe Größe wie in der .Net-Datei und C ++ - Datei ), der Inhalt ist jedoch unterschiedlich:
Wie Sie sehen können, ist es ähnlich, aber nicht gleich. Als Folge dieser Differenz kann CPP-Code .NET-C # -Nachrichten lesen, während .NET CPP-Nachrichten nicht lesen kann .
Im Code zur Deserialisierung erhalten wir:
Eine nicht behandelte Ausnahme vom Typ 'System.InvalidCastException' ist aufgetreten in TestProto.exe
Zusätzliche Informationen: Objekt des Typs kann nicht umgewandelt werden 'TestProto.EventBase', um 'TestProto.EventCharacterMoved' einzugeben.
in Code wie:
%Vor% Schauen wir uns an (wie in jpa in seinem Kommentar erwähnt) protoc --decode_raw
option:
Dies kann damit zusammenhängen, dass mein CPP-Wrapper die neueste Google-Protobuf-Version verwendet, während protobuf-net wahrscheinlich ein älteres Kodierungsformat oder etwas ähnliches verwendet ...
Ich frage mich also, wie man .NET-Protobuf C ++ - Nachrichten lesen kann (damit das gleiche Zeug entschlüsselt werden kann)?
Oder zumindest, wie man originalen Google-Protobuf encodieren kann, genauso wie .NET-Protobuf?
Und für diejenigen, die wirklich interessiert sind und gerne in das Zip-Bundle mit vereinfachtem Beispiel (VS 2010-Lösungen) einsteigen möchten für C ++ und C # Code enthalten)
Bearbeiten; Dies sollte in r616 und darüber behoben werden.
Ich hatte endlich die Chance, das zu betrachten (Entschuldigung für Verspätung, aber soziale saisonbedingte Feiertagsforderungen). Ich verstehe, was jetzt passiert.
Grundsätzlich sind die Daten theoretisch identisch; Worauf es eigentlich ankommt, ist die Feldordnung. Technisch gesehen werden Felder normalerweise in aufsteigender Reihenfolge geschrieben, können aber in beliebiger Reihenfolge erwartet werden. In Bezug auf Protobuf-Net; Für Typen, die keine Vererbung beinhalten, funktioniert es unabhängig von der Reihenfolge. Die Protobuf-Spezifikation definiert keine Vererbung, daher fügt protobuf-net Unterstützung (aufgrund der konstanten Nachfrage) zusätzlich zu der Spezifikation hinzu. Als ein Implementierungsmerkmal schreibt es die Unterklasseninformation zuerst (d. H. Feld 15, der Untertyp, wird vor Feld 10 geschrieben). Zur Zeit der Deserialisierung erwartet die Information des Untertyps zuerst. Dies hat selten jemanden beeinflusst, da protobuf-net die einzige Implementierung ist, die eine Vererbung wie diese verwendet, die Verwendung der Vererbungsfunktion wird meistens nur mit der Verwendung von protobuf-net zu protobuf-net gesehen.
In Ihrem Fall verwenden Sie .proto, um mit CPP zu interagieren. Das bedeutet, dass der CPP-Code in der Lage ist, Daten von protobuf-net zu konsumieren, aber möglicherweise eine type-Cast-Ausnahme hat (im Grunde beginnt er, den konkreten Typ zu dem Zeitpunkt zu konstruieren, zu dem er das erste Datenfeld erhält) / p>
Obwohl dies selten ein Problem ist, muss dies behoben werden. Ich kann versuchen, mir das heute oder morgen anzuschauen.
Optionen:
EventBase
mit nur die EventCharacterMoved
-Daten und serialisieren Sie sie; Schreiben Sie nun in einem separaten Modell ein EventBase
mit nur die TreeFloat
-Daten und serialisieren Sie; Dies simuliert das Schreiben in der erforderlichen Reihenfolge (Protobuf-Streams sind anhängbar) - nicht hübsch Tags und Links .net c# c++ protocol-buffers protobuf-net