char Array als Struktur interpretieren

Gast #1599028
Hallo,

ich empfange Kommando-Datenpakete(kein einheitliches Format) über die 
serielle Schnittstelle und speicher diese erstmal in einem char Buffer 
ab.

Ich wollte nun verschiedene structs definieren, und den Buffer je nach 
Datenpaket als einen dieser Structs interpretieren um die Daten 
einfacher verarbeiten zu können und nicht per Indizies auf den Buffer 
zugreifen zu müssen.

Ich weiß aber nun nicht genau, wie ich das anstelle, das ich den Buffer 
als struct interpretieren kann. Muss ich den buffer zu einem struct 
casten?

Irgendwie finde ich bei google kein leicht verständliches Beispiel bzw. 
fehlt mir irgendwie das Stichwort dafür.

Gehen sollte das doch aber irgendwie, oder?
#1599037
honkytonky schrieb:

> Ich weiß aber nun nicht genau, wie ich das anstelle, das ich den Buffer
> als struct interpretieren kann. Muss ich den buffer zu einem struct
> casten?

Fast. Du castest dir einen Pointer auf den Anfang des Buffers um zu 
einem Pointer auf die Struktur.
1
struct irgendwas
2
{
3
  int member1;
4
  int member2;
5
};
6

7
int main()
8
{
9
  char buffer[20];
10
  struct irgendwas* pStruct;
11

12
  .... buffer kriegt seinen Wert
13

14
  pStruct = (struct irgendwas*)buffer;
15

16
  mach was mit pStruct->member1;
17
  mach was mit pStruct->member2;
Gast #1599762
Noch eine Anmerkung:

sowas funktioniert nur zuverlässig auf 8 Bit CPUs (was hier 
wahrscheinlich aber gegeben ist).

Bei > 8 Bit fügt der Compiler u.U. zusätzliche Bytes in die Struktur 
ein, Stichtwort: Alignment.
Je nachdem, was man dem Compiler beim Erstellen dazu mitteilt bzw. zu 
was man ihn auffordert.
Gast #1599777
Zur Anmerkung:

honkytonky schrieb:
> ich empfange Kommando-Datenpakete(kein einheitliches Format) über die
> serielle Schnittstelle und speicher diese erstmal in einem char Buffer
> ab.

In dem Fall ist die Spielerei mit den Strukturen sowieso eine blöde 
Idee, da zwei Maschinen mit u.U. verschiedenen Endiannesses im Spiel 
sind.
Gast #1599856
öh...Endiannesses?  little endian, big endian oder wie? hmmm...ne, ich 
glaube nicht das ich davon betroffen bin

ja, es handelt sich um eine 8bit CPU und was für Möglichkeiten habe ich 
denn sonst, so eine Datenpaket möglichst geschickt zu parsen??
Die ganze Zeit mit den Buffer-Indizies zu arbeiten ist sehr 
unübersichtlich. Da ist ein bischen Klartext schon hilfreicher.

Und bisher funktioniert das nach der von Karl-Heinz geposteten Methode.

Falls jemand was besseres weiß dann nur her damit. Mich verwirrt diese 
Poiterei nämlich immer recht schnell :(
Gast #1599871
Naja, dein Problem ist recht simpel. In der Netzwerktechnik gibt es 
genau deshalb z.B. die Funktionen htons/ntohs usw.

Beispiel:
Du überträgst den Datenstrom zeichen(byte)weise ein. Nun hast du vom 
Sender einen vier Bytes breiten Integer (zwei Bytes reichen natürlich 
auch schon). Der Sender geht hin und überträgt die vier Bytes der Reihe 
nach, von der ersten bis zur vierten Speicherstelle.

Der Empfänger geht nun hin und liest die vier Bytes der Reihe nach und 
schreibt sie hintereinander in die vier Speicherstellen eines Integers.

Was passiert nun, wenn beim Sender die erste Speicherstelle das Byte mit 
den Stellen 0 bis 7 war, beim Empfänger aber das Byte mit den Stellen 
24..31?
Gast #1599875
Du kannst den Compiler u.U. zwingen, keine Füllbytes in Strukturen 
einzubauen.
Beim GCC gehts (glaube ich) so:
1
struct test_t {
2
  int  a;
3
  char b;
4
  int  c;
5
} __attribute__((__packed__));
Gast #1600532
Bei einer 8 Bit CPU ists ja wurscht, ich wollte nur darauf hinweisen.

Weil im Ursprungspost steht nichts von der Zielplattform.


Ich gehe mal davon aus, dass Du Byte-für-Byte über die Leitung schickst, 
und genau weisst, welches Byte wie zu verarbeiten und von welchem 
Datentyp ist.
Ansonsten solltest Du dir natürlich dann nochmal Gedanken zur 
HW-Architektur der Senderseite etc. machen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.