Wie konvertiert man 'struct' in '& [u8]'?

9

Ich möchte meine Struktur über ein TcpStream senden. Ich könnte String oder u8 senden, aber ich kann keine beliebige Struktur senden. Zum Beispiel:

%Vor%

Nach Erhalt der Daten möchte ich &[u8] zurück in MyStruct konvertieren. Wie kann ich zwischen diesen beiden Darstellungen konvertieren?

Ich weiß, dass Rust über ein JSON-Modul zum Serialisieren von Daten verfügt, aber ich möchte JSON nicht verwenden, weil ich Daten so schnell und so klein wie möglich senden möchte, damit ich keinen oder sehr geringen Overhead haben möchte.

    
agatana 24.01.2015, 15:43
quelle

2 Antworten

9

(Schamlos aus Renato Zannons Kommentar zu einer ähnlichen Frage gestohlen )

Vielleicht würde eine Lösung wie bincode zu Ihrem Fall passen? Hier ist ein Arbeitsbeispiel:

Cargo.toml

%Vor%

main.rs

%Vor%

Sie könnten dann die Bytes senden, wo immer Sie wollen. Ich nehme an, Sie sind sich der Probleme mit dem naiven Senden von Bytes bereits bewusst (wie potentielle Endianness-Probleme oder Versionierung), aber ich erwähne sie nur für den Fall ^ _ ^.

    
Shepmaster 24.01.2015, 15:55
quelle
9

Eine korrekt dimensionierte Struktur als nullkopierte Bytes kann mit stdlib und einer generischen Funktion erstellt werden.

Im folgenden Beispiel gibt es eine wiederverwendbare Funktion namens any_as_u8_slice anstelle von convert_struct , da dies ein Dienstprogramm zum Umbrechen der Cast- und Slice-Erstellung ist.

Beachten Sie, dass bei der Frage nach converting gefragt wird. In diesem Beispiel wird eine schreibgeschützte Schicht erstellt, was den Vorteil hat, dass Sie den Speicher nicht kopieren müssen.

Hier ein Arbeitsbeispiel basierend auf der Frage:

%Vor%

Hinweis 1) obwohl die Kisten von Drittanbietern in einigen Fällen besser sind, ist dies eine so primitive Operation, dass es nützlich ist, in Rust zu wissen.

Hinweis 2) zum Zeitpunkt des Schreibens (Rust 1.15) gibt es keine Unterstützung für const -Funktionen. Sobald dies der Fall ist, wird es möglich sein, in ein Array fester Größe anstelle eines Slices zu werfen.

Hinweis 3) Die Funktion any_as_u8_slice ist mit unsafe gekennzeichnet, da alle Füllbytes in struct nicht initialisierter Speicher sein können (undefiniertes Verhalten). Wenn es einen Weg gäbe, um sicherzustellen, dass die Eingabeargumente nur Strukturen verwenden, die #[repr(packed)] sind, dann ist dies der Fall könnte sicher sein.

Ansonsten ist die Funktion relativ sicher, da sie einen Pufferüberlauf verhindert, da die Ausgabe schreibgeschützt ist, eine feste Anzahl von Bytes hat und ihre Lebensdauer an die Eingabe gebunden ist.
Wenn Sie eine Version wünschen, die% zurückgibt co_de%, das wäre ziemlich gefährlich, da das Ändern leicht inkonsistente / beschädigte Daten erzeugen könnte.

    
ideasman42 12.02.2017 10:39
quelle

Tags und Links