Objekt im Speicher: Füllbytes?
-
Ich habe gerade den Fall, das ich ein Objekt verschicken (mit byte-Zeiger und sizeof für die Anzahl der Bytes) wollte und mich auf der Empfängerseite gewundert habe, wieso da immer mehr ankommt, als geplant. Hier mal ein Speicherabbild eines Objekts:
http://www.abload.de/img/paddingbytesz1jxv.png
- Blau markiert sind die eigentlichen Größen der Variablen (1 Byte oder 2 Byte).
- Rot markiert sind die Stellen, an dem der Compiler ein Füllbyte eingefügt hat. Aus dem Byte mit der "07" wurde also beim verschicken ein WORD. Außerdem wird ganz am Ende noch ein überflüssiges Byte mitgeschickt.Meine Fragen:
1.) Das sind doch Füllbytes vom Compiler, oder?
2.) Kann man das ausstellen? Falls ja, das Unterdrücken von Füllbytes wird nicht sinnvoll sein, korrekt?
3.) Die vielleicht wichtigste Frage:
Wie verschicke ich jetzt das Speicherabbild eines Objekts als Byte-stream übers Netz? Das Programm läuft auf einem Mikrocontroller, also nix mit boost oder sonstwas. Auf der Empfängerseite lauscht Java.Ich würde jetzt mit den ganz normalen "gettern" des Objekts arbeiten und verschicken. Folgendes sah aber so viel eleganter und kürzer aus
:BYTE *pStruct = (BYTE*) &myStruct; BYTE bytesToSend = sizeof(myStruct); while(bytesToSend) { m_pSerial->send(*pStruct); ++pStruct; --bytesToSend; }Vorschläge willkommen
-
Ich glaube, der Standard schreibt nicht vor, wie die Struktur der Member in deinem Objekt aussieht. In der Realität padden daher die Compiler Klassen so, dass alle Member "naturally aligned" sind. Mit Visual Studio kannst du dieses Padding-Verhalten kontrollieren (http://msdn.microsoft.com/en-us/library/2e70t5y1(VS.80).aspx) Wenn du eine portable Lösung willst, könntest du alle Membervariablen deiner Klasse erst per memcpy in ein byte-array kopieren (solange es sich um POD's handelt) und dieses dann verschicken.
-
Die Compiler haben meist ein eine Möglichkeit ( #pragma pack oder soetwas ), um das zu beeinflussen.
-
Um mal ein wenig vorzukauen:
#pragma pack(push) #pragma pack(1) class myStruct { //bla bla bla.. }; #pragma pack(pop)Nun ist der Type myStruct auf 1 Byte aligenment gesetzt, d.h. aligenment ist ausgeschaltet und es gibt keinerlei "extra" bytes.
Das push und pop ist dafür da, denn aligenment Wert zu speichern und wieder auf den Standardwert zurückzusetzen.Zu 3:
Was ist denn überhaupt das Interface zum MC? TCP/IP?
-
Interface ist UART.
Ich bin mir aber unsicher ob man Padding jetzt deaktivierne sollte oder nicht, das wird doch seine Gründe haben (Performance?)
-
Was macht ihr eigentlich immer für abgefahrene Sachen, wenn ihr bei Verbindung zu einem MC direkt von TCP/IP ausgeht? Oo Könnte man ja noch JSON drüberbauen und vielleicht mit Mono auf dem MC dann endlich die .NET-Welt erleben!
-
Wie verschicke ich jetzt das Speicherabbild eines Objekts als Byte-stream übers Netz?
Gar nicht, Serialisiere und Deserialisiere ordentlich. Damit meine ich nicht XML oder ASCII. Beachte Little- und Big-endian!
-
knivil schrieb:
Wie verschicke ich jetzt das Speicherabbild eines Objekts als Byte-stream übers Netz?
Gar nicht, Serialisiere und Deserialisiere ordentlich. Damit meine ich nicht XML oder ASCII. Beachte Little- und Big-endian!
Brauche da mehr Informationen zu. Mir ist die Bedeutung von serialisieren klar und wie das z.b. in Java erfolgt.
Aber was ist "ordentliches serialisieren" in Bezug auf Objekten die auf Microcontrollern existieren?
-
Um was für nen uC geht's hier eigentlich? Gut möglich, dass es Sinn macht, das Protokoll dem uC auf den Leib zu schneidern, damit der Serialisierungsaufwand auf der schwächeren Seite entfällt. Das hängt aber davon ab, wie zeitkritisch deine Anwendung ist und ob wir uns hier so in der Größenordnung eines ATtiny oder eines ARM bewegen.