Datum:
Hallo! Wenn ich eine Struktur anlege, die z.B. so aussieht:
typedef struct DataBlock_Struct { unsigned char destination; unsigned char source; unsigned char length; unsigned char data[20]; unsigned char crc; } DataBlock, *DataBlock_p; DataBlock dataToSend; |
Was muss ich tun, dass die Reihenfolge der Variablen innerhalb der Struktur auch der im Speicher ist, dass ich diese quasi serialisiert senden kann (send(&dataToSend[0])? Wenn die Firmware des Senders die gleiche ist, wie die des Empfängers ist, ist die Wahrscheinlichkeit hoch, dass es passt. Bei Unterschiedlichen gibt es doch keine Gewähr. Oder gibt es hier einen Trick? Gruß Jochen
Datum:
Jochen schrieb: > Bei Unterschiedlichen gibt es doch keine Gewähr. Oder gibt es hier einen > Trick? ja gibt es - verzichte auf die stuct. Sende die Daten einzeln dann stimmt es immer. Wenn du unbedigt die stuct verwenden willst, solltest du in der doku von deinem compieler lesen wie du sie "packt" ablegen kannst.
Datum:
Von welcher Firmware redest du? Die Reihenfolge ist m.W. nicht prinzipiell garantiert und kann (zusammen mit evtl. eingefügten Füllbytes) vom Compiler, dessen Version und ggf. Compileroptionen abhängen. Wenn man eine Reihenfolge wasserdicht erzwingen will, sind also structs fehl am Platz; eine alternative wäre ein uint8_t-Array, auf das man mit unions oder Zeigermimik die eigentlichen Werte drüberlegt. Naja. Allerdings kenne ich keinen C-Compiler, der die Elemente einer struct in einer anderen Reihenfolge als der angegebenen ablegt. Insofern würde ich vermutlich einfach die Reihenfolge als gegeben hinnehmen.
Datum:
Peter II schrieb: > ja gibt es - verzichte auf die stuct. Sende die Daten einzeln dann > stimmt es immer. Dann habe ich aber kleine, aber dennoch messbare und unerwünschte Sendepausen, wenn ich einen "Kontextwechsel" durchführen muss. Bei einem Byte-Stream, kann ich einfach "durchsenden". Klaus Wachtler schrieb: > eine alternative wäre ein uint8_t-Array, auf das man mit > unions oder Zeigermimik die eigentlichen Werte drüberlegt. Sind Unions!? Da fängt doch alles bei der gleichen Adresse an und die größte Variable bestimmt die Größe der Union ... !?
Datum:
Jochen schrieb: > Dann habe ich aber kleine, aber dennoch messbare und unerwünschte > Sendepausen, wenn ich einen "Kontextwechsel" durchführen muss. eigentlich nicht, dann die sendeeinheit hat doch wohl noch einen kleinen sendepuffer. Dieser reicht aus um die nächsten daten reinzuschieben.
Datum:
Schreibe dir Funktionen die ein gewünschtes Struct in ein Byte Array umwandeln und aus einem Byte Array wieder eine solche Struktur erzeugen. Gesendet und empfangen wird dann das Byte Array. So ist es transparent und unabhängig und du brauchst keine Sendefunktionen für n verschiedene Daten, sondern nur eine für bytes.
Datum:
Udo Schmitt schrieb: > Schreibe dir Funktionen die ein gewünschtes Struct in ein Byte Array > umwandeln und aus einem Byte Array wieder eine solche Struktur erzeugen. > Gesendet und empfangen wird dann das Byte Array. > So ist es transparent und unabhängig und du brauchst keine > Sendefunktionen für n verschiedene Daten, sondern nur eine für bytes. Serialisieren und deserialisieren ...
Datum:
Jochen schrieb: > Serialisieren und deserialisieren ... Jepp, den Begriff hast du ja schon verwendet: Jochen schrieb: > dass ich diese quasi serialisiert senden kann (send(&dataToSend[0])? Nachtrag. Wenn es portabel sein soll macht es immer Sinn multibyte Variablen unabhängig von der Hardware einheitlich zu serialisieren (Stichwort net byte ordering)
Datum:
Udo Schmitt schrieb: > Nachtrag. Wenn es portabel sein soll macht es immer Sinn multibyte > Variablen unabhängig von der Hardware einheitlich zu serialisieren > (Stichwort net byte ordering) Ist das diese LSB-, MSB-Thematik!?
Datum:
Bzw. Big- Little Endian... Gibt es dafür Beispielcode?
Datum:
Klaus Wachtler schrieb: > Die Reihenfolge ist m.W. nicht prinzipiell garantiert und kann (zusammen > mit evtl. eingefügten Füllbytes) vom Compiler, dessen Version und ggf. > Compileroptionen abhängen. Die Reihenfolge ist garantiert, der Compiler darf nur Füllbytes einfügen.
Datum:
Andreas B. schrieb: > Die Reihenfolge ist garantiert, der Compiler darf nur Füllbytes > einfügen. Da bei Jochen alle Daten als "unsigned char" deklariert sind, kommen auch keine Füllbytes in Frage, denn char braucht (unabhängig von der Bitanzahl, die es belegt) nie zusätzliches Padding.
Datum:
Jörg Wunsch schrieb: > Da bei Jochen alle Daten als "unsigned char" deklariert sind, > kommen auch keine Füllbytes in Frage, denn char braucht (unabhängig > von der Bitanzahl, die es belegt) nie zusätzliches Padding. Ich hatte mir das Struct gar nicht genau angeschaut. Mir gings um die prinzipielle Vorgehensweise, weil das immer wieder Thema ist Wie sieht das bei Array von characters aus. Da ist ein char Array dabei. Wird das ggf. auf manchen Maschinen auf durch 2 (4) teilbare Adressen gelegt?
Datum:
Jochen schrieb: > Udo Schmitt schrieb: >> Nachtrag. Wenn es portabel sein soll macht es immer Sinn multibyte >> Variablen unabhängig von der Hardware einheitlich zu serialisieren >> (Stichwort net byte ordering) > > Ist das diese LSB-, MSB-Thematik!? Ja. Suche einfach nach ntohs, htons bzw. ntohl, htonl. (Falls du es überhaupt brauchst.) Der kleine zottelige Jedi ist auch nicht verkehrt. http://www.zotteljedi.de/socket-tipps/xtox.html
Datum:
Udo Schmitt schrieb: > Wie sieht das bei Array von characters aus. Da ist ein char Array dabei. > Wird das ggf. auf manchen Maschinen auf durch 2 (4) teilbare Adressen > gelegt? Nö, gibt's keinen Grund dafür. Vorsicht ist mit so einer struct natürlich auf (exotischen) Maschinen geboten, bei denen CHAR_BIT != 8 ist.
Datum:
Jörg Wunsch schrieb: > Da bei Jochen alle Daten als "unsigned char" deklariert sind, In diesem Beispiel. Es gibt aber auch Structs mit long- und double-Werten raute schrieb: > Suche einfach nach ntohs, htons bzw. ntohl, htonl. (Falls du es > überhaupt brauchst.) Wollte eigentlich unabhängig von fertigen Bibliotheken sein ...
Datum:
Jochen schrieb: >> Da bei Jochen alle Daten als "unsigned char" deklariert sind, > > In diesem Beispiel. Es gibt aber auch Structs mit long- und > double-Werten Dann solltest du besser passende Beispiele posten. ;-) Du bist immer auf der sicheren Seite, wenn du bei verschiedenen Plattformen jegliches mögliches Padding von vornherein mit in der Struktur unterbrings bzw. die Struktur passend aufbaust. Dazu geht man vom größeren zum kleineren Datentyp vor. Wenn du also double-Elemente hast, kommen diese am Anfang, gleichfalls andere 64-bit-Typen. Danach kommen die 32-bit-Elemente usw. usf. An der Grenze zwischen den verschiedenen Größten musst du ggf. dann die Füllbytes auffüllen, die der Compiler ohnehin auffüllen müsste, die benennst du dann eben einfach selbst, ohne sie am Ende zu benutzen. > raute schrieb: >> Suche einfach nach ntohs, htons bzw. ntohl, htonl. (Falls du es >> überhaupt brauchst.) > > Wollte eigentlich unabhängig von fertigen Bibliotheken sein ... Das sind keine Bibliotheken, sondern Makros bzw. Inline-Funktionen, die man auf der jeweiligen Zielplattform so effizient wie möglich realisiert. Manche CPUs haben dafür gleich eigene Befehle parat. Wenn die Zielmaschine bereits "network byte order" benutzt (also big endian), sind diese Teile Nullmakros.
Datum:
Hallo ! Wollte nur zusätzlich auch noch folgenden Link zum Thema einwerfen: http://www.parashift.com/c++-faq-lite/serialization.html Beste Grüße