2017-05-18 2 views
0

Angenommen, wir schreiben eine C++ - Netzwerkanwendung mit UDP-Sockets. Wir brauchten eine nicht-so-kleine Packung von Daten zu übergeben, und so nehmen wir diese Art von Struktur, um sicherzustellen, die Byte-Reihenfolge ist das Netzwerk ein:Tragbare Alternative für gepackte Strukturen mit einem flexiblen Array-Element

struct [[gnu::packed]] datagram { 
    uint64_t timestamp; 
    uint8_t type; 
    uint32_t temperatures[60]; // whatever, just an example 
    uint8_t raw_data[]; 
}; 

Wir GNU GCC verwendet hat, so dass wir nutzten nicht-Standard-C++ Funktionen wie

  • flexiblen Feldelements
  • gepackten Struktur

wir brauchten eine gepackte Struktur, da wir zwischendurch nicht padding wollen, da dieser Architekt sein kann ure-abhängig, und unser Netzwerkprogramm kann auf verschiedenen Architekturen laufen.

Dann, nach einem Jahr, kann es herauskommen, dass wir einen Nicht-GCC-Compiler unterstützen müssen, der diese nicht unterstützt.

Ist es möglich, dies in Standard C++ zu tun?

Natürlich weiß ich, wir könnten einfach einen uint8_t buffer[SOME_SIZE] verwenden und memcpy jeden Teil des Datagramms, aber das klingt wie eine gute Möglichkeit, schrecklichen, wirklich hässlichen Code zu erstellen.

+4

Suchen und verwenden Sie eine Serialisierungsbibliothek. Dieses Problem wurde viele Male gelöst, aber die Leute bestehen darauf, es immer und immer wieder zu tun, weil keine der Lösungen gut ist. – nwp

Antwort

3

[[gnu::packed]] ist eine schreckliche Möglichkeit, Serialisierung zwischen beliebigen Architekturen zu tun. Es gibt immer noch Big-Endian-Maschinen da draußen.

Der richtige Weg, dies zu tun ist, ein Serialisierungsformat in Bezug auf Oktette zu definieren, und dann zwischen einem Oktettstrom (zu oder von dem UDP-Socket) und einer übersichtlichen Struktur zu konvertieren.

Es gibt viele Bibliotheken, die dies einfach machen. Wir verwenden protobuf bei der Arbeit; Ein früherer Arbeitgeber hatte eine selbstgebraute Lösung. (Beachten Sie, dass eine Anforderung für eine Empfehlung für eine solche Bibliothek für Stapelüberlauf explizit nicht relevant ist.)

+0

Sicher, so können Sie die Daten in der Struktur in Netzwerk-Byte-Reihenfolge behalten. Bearbeitete das OP. – marmistrz