Serialisierung/Deserialisierung ein struct mit einem char* in C
Habe ich ein struct
struct Packet {
int senderId;
int sequenceNumber;
char data[MaxDataSize];
char* Serialize() {
char *message = new char[MaxMailSize];
message[0] = senderId;
message[1] = sequenceNumber;
for (unsigned i=0;i<MaxDataSize;i++)
message[i+2] = data[i];
return message;
}
void Deserialize(char *message) {
senderId = message[0];
sequenceNumber = message[1];
for (unsigned i=0;i<MaxDataSize;i++)
data[i] = message[i+2];
}
};
Muss ich konvertieren Sie diese zu einem char* , maximale Länge MaxMailSize > MaxDataSize für das senden über das Netzwerk und dann deserialisiert es am anderen Ende
Kann ich nicht verwenden, tpl oder andere Bibliothek.
Gibt es eine Möglichkeit, das besser zu machen, ich bin nicht so komfortabel mit diesem, oder ist das das beste, was wir tun können.
InformationsquelleAutor Ankur Chauhan | 2009-10-31
Du musst angemeldet sein, um einen Kommentar abzugeben.
da diese werden über ein Netzwerk gesendet werden, empfehle ich dringend, die Sie konvertieren die Daten in Netzwerk-byte-Reihenfolge vor der übertragung, und zurück in host-byte-order beim Empfang. dies ist, da die byte-Reihenfolge ist nicht die gleiche überall, und wenn Sie Ihren bytes werden nicht in der richtigen Reihenfolge, kann es sehr schwierig werden, diese rückgängig machen (abhängig von der verwendeten Programmiersprache auf der empfangenden Seite). die byte-Reihenfolge-Funktionen definiert sind, zusammen mit sockets und named
htons()
,htonl()
,ntohs()
undntohl()
. (in diesen Namen: "h" bedeutet "host" oder Ihrem computer, n bedeutet 'Netzwerk', s bedeutet 'kurz' - oder 16-bit-Wert, l bedeutet "long" oder 32-bit-Wert).dann sind Sie auf Ihre eigenen mit Serialisierung, C und C++ haben keine automatische Möglichkeit, um es auszuführen. einige Software können code generieren, um es für Sie tun, wie die ASN.1 Umsetzung asn1c, aber Sie sind schwierig zu benutzen, denn Sie beinhalten viel mehr als nur Daten über das Netzwerk kopieren.
InformationsquelleAutor Adrien Plisson
Können Sie eine Klasse reprensenting das Objekt, das Sie verwenden in Ihrer software mit allen Feinheiten und Mitglied func und was auch immer Sie brauchen. Dann haben Sie 'serialisiert' struct, das mehr eine Beschreibung von dem, was am Ende auf das Netzwerk.
Zur Gewährleistung der compiler tun, was Sie ihm sagen zu tun, müssen Sie zu belehren, dass es "pack' die Struktur. Die Richtlinie habe ich hier, ist für den gcc finden Sie in Ihrem compiler-doc, wenn Sie nicht mit gcc.
Dann das serialisieren und Deserialisieren von routine konvertieren zwischen den beiden, die Gewährleistung der byte-Reihenfolge und details wie die.
delete ptr
? Es ist schon eine Weile her, seit ich gearbeitet in C++, aber da bist du allokierung von heap-Speicher, den Sie brauchen, um deallocate es irgendwo.Mmmm, Nein wahrscheinlich nicht (zumindest nicht garantiert). Es ist wahrscheinlich besser, verwenden Sie malloc() und free() dann.
Oder besser noch, vergessen allokierung von Speicher auf dem heap; verwenden die gleichen internen stack-Puffer für die Serialisierung und Deserialisierung
Wie kann das funktionieren, wenn die Unterschrift ist ein void* ist in der Umsetzung, char* in der Verlangsamung, sondern s die variable, die Sie zurückgeben, ist ein SerializedPacket?
Ich möchte an dieser für die übertragung der Daten über das Netzwerk. Wird es ein Problem mit Bezug auf endian Unterschiede?
InformationsquelleAutor 246tNt
Je nachdem, ob Sie genug haben oder nicht... Sie können einfach zu den streams 🙂
Ich gebe zu, es braucht mehr Platz... oder, es könnte so sein.
Tatsächlich, auf einem 32-bit-Architektur eine
int
decken in der Regel 4 bytes (4 char). Serialisieren Sie mit streams nur mehr als 4 'char', wenn der Wert überlegen ist 9999, welcher in der Regel gibt einige Zimmer.Beachten Sie auch, dass Sie sollten wahrscheinlich einige Wachen in Ihrem stream, nur zu überprüfen, wenn Sie bekommen es zurück, dass es in Ordnung ist.
Versionierung ist es wahrscheinlich eine gute Idee, Sie kostet nicht viel und ermöglicht ungeplante späteren Entwicklung.
InformationsquelleAutor Matthieu M.
Sind Sie überschreiben die Werte hier. senderId und sequenceNumber sind beide int-Werte und auch mehr als sizeof(char) bytes auf den meisten Architekturen. Versuchen Sie so etwas wie dieses:
BEARBEITEN:
fixed-code, geschrieben in einem stupor. Auch, wie bereits im Kommentar, jeder wird ein solches Paket ist nicht beweglich durch endian Unterschiede.
memcpy(message + offset, &senderId, sizeof(senderId))
. Auch müssen Sie nicht die letzten memcpy, wiedata
müssen nicht serialisiert werden, da es lediglich der Puffer für unserialization.Er ist nicht überschreiben alles, was bei der Zuordnung eines
int
zu einemchar
. Er ist (möglicherweise) mit dem abschneiden Ihrer Werte, obwohl.-1 Die Verwendung von
memcpy
fürsenderId
undsequenceNumber
ist nicht tragbar, da Sie nicht garantieren können, die byte-Reihenfolge für diese Werte. Besser, es zu tun mit der Verschiebung und der Maskierung.Ich klar, sollte nicht auf Fragen zu Antworten, so spät in der Nacht. @Charles, ich weiß, er war mit dem abschneiden von Werten, aber ich war das denken in Bezug auf seine Absicht, und hatte gewesen, mit diesen Ziel-offsets mit memcpy, er hätte überschrieben, die letzten 3 bytes senderId
InformationsquelleAutor Jherico
Ihre Frage zu beantworten in der Regel, C++ hat keine reflection-Mechanismus, und so manuelle serialize und unserialize Funktionen definiert, die auf einer pro-Klasse basis ist die beste, die Sie tun können. That being said, die Serialisierung Funktion, die Sie geschrieben wird mangle Ihre Daten. Hier ist eine korrekte Umsetzung:
InformationsquelleAutor Charles Salvia
Wie erwähnt in anderen Beiträgen,
senderId
undsequenceNumber
sind beide vom Typint
, die wahrscheinlich größer ist als der char, so werden die Werte abgeschnitten.Wenn das akzeptabel ist, dann ist der code OK. Wenn nicht, dann müssen Sie zu Spalten Sie in Ihre Bestandteile bytes. Gegeben, dass das Protokoll Sie verwenden, wird die genaue Angabe der byte-Reihenfolge von multi-byte-Feldern, die meisten tragbaren und am wenigsten zweideutige Art und Weise, dies zu tun ist durch eine Verschiebung.
Zum Beispiel, sagen wir mal, dass
senderId
undsequenceNumber
sind beide 2 bytes lang ist, und das Protokoll verlangt, dass das höherwertige byte zuerst geht:Ich würde auch empfehlen das ersetzen der
for
Schleife mitmemcpy
(wenn verfügbar), da es unwahrscheinlich ist, weniger effizient zu sein, und es macht den code kürzer.Schließlich alle davon ausgegangen, dass
char
ist ein byte lang. Wenn nicht, dann alle Daten müssen maskiert werden, z.B.:InformationsquelleAutor Steve Melnikoff
Können Sie verwenden, Protocol Buffers für die Definition und die Serialisierung von Strukturen und Klassen. Dies ist, was google intern verwendet, und hat eine sehr geringe transfer-Mechanismus.
http://code.google.com/apis/protocolbuffers/
InformationsquelleAutor Stef