Hallo zusammen, ich spiele gerade ein ein wenig mit UDP herum. Ich empfange per UDP nacheinander mehrere Array's zwischen 25-1341 Bytes. Diese möchte ich in entsprechende Strukturen ablegen, die auch definiert sind. Nur stehe ich auf dem Schlauch, da ich nicht weiß wie ich es umkopieren soll. memcpy funktioniert ja nicht, da das jeweilige Struct, aus verschiedenen Datentypen besteht, wie int16, float etc. Wie stelle ich das am besten an? Gruß Anfänger
Entweder schreibst Du Dir entsprechende Konverter, die jedes Byte einzeln bearbeiten, .... Oder du stellst sicher, dass endianess, allignment und packing gleich sind, dann memcpy oder Struktur-zuweisung.
Arduino Anfänger schrieb: > memcpy funktioniert ja nicht, da das jeweilige Struct, aus verschiedenen > Datentypen besteht, wie int16, float etc. Wieso sollte es das nicht tun? Natürlich kann man Strukturen per memcpy kopieren. Das geht nur dann nicht, wenn das empfangene Strukturabbild nicht dem Deiner Zielstruktur entspricht. Daß Du Deine Daten zunächst als uint8_t-Array empfängst, hat nichts mit der Art des Strukturabbildes zu tun.
> Nur stehe ich > auf dem Schlauch, da ich nicht weiß wie ich es umkopieren soll. Du koenntest das automatisch im Hintergrund vom Compiler machen lassen. Hier mal ein Beispiel wie ich das mache: struct HeaderType { uint32_t crc32; //Prüfsumme des Datenstructes uint16_t length; //Laenge des Datenstructes uint8_t UsedDataType; //Type des Datenstructes uint8_t Version; //Version des Datenformates uint32_t UpCounter; //Ein Zaehler den der Sender bei jedem Paket um 1 erhoeht uint8_t encoding; //0= keine Verschluesselung uint8_t unused1; //fuer zukuenftige Erweiterungen uint8_t unused2; //fuer zukuenftige Erweiterungen uint8_t crc8; //Pruefsumme das HeaderTypes } _attribute_ ((packed)); union HeaderUnion { struct HeaderType Header; uint8_t Byte[16]; }; [..] HeaderUnion UDP_Header; [..] //Den Header kopieren for(i=0; i<sizeof(HeaderUnion); i++) { UDP_Header.Byte[i] = *UDP_Paket++; } [..] //Pruefsumme des Header okay? if (UDP_Header.Header.crc8 != CRC8(UDP_Header.Byte, sizeof(HeaderUnion) -1 ) ) return ( UDP_HEADER_\ CRC); Das funktioniert, sieht elegant aus, setzt aber voraus das du verstehst was du machst weil es abhaengig von Compiler und Wordbreite im Controller sein kann. Aber bei der geeigneten Wahl von Pruefsummen von Header und Daten faellt man nicht so schnell auf die Nase. Olaf
Olaf schrieb: > Das funktioniert Ist in C aber unportabel und in C++ (Arduino!) ganz verboten (siehe den Artikel).
> Ist in C aber unportabel und in C++ (Arduino!) ganz verboten (siehe den > Artikel). Auf die Probleme hab ich hingewiesen. Lustigerweise ist das ein Codeausschnitt den ich verwende um von meinem PC aus (Qt) die Helligkeit meiner Schreibtischlampe (ESP8266/Arduino) einzustellen. Es ist also wohl doch nicht ganz verboten und nicht ganz unportabel. Und da ich sowohl fuer header wie auf fuer Daten jeweils eine Pruefsumme verwende wuerde es mir auffallen sollte es doch irgendwann mal ein Problem geben. p.s: die Methode zur en/dekodierung meiner Daten in/aus einem UDP-Paket verwende ich 1:1 kopiert, sowohl in Arduino wie auch im Qt-Programm. Olaf
Olaf schrieb: > Es ist also wohl doch nicht ganz verboten und nicht ganz > unportabel. Das ist ja die Tücke an Undefined Behaviour (d.h. "verbotenen" Dingen) - es kann den Anschein haben zu funktionieren, und wenn du eine Kleinigkeit änderst (Compiler, -Version, -Optionen, Plattform, ...) klappt es nicht mehr. Das Argument "funktioniert doch" zieht hier also nicht. In Serialisierung ist das alles erläutert und begründet, inklusive korrekter Lösungen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.