mikrocontroller.net

Forum: PC-Programmierung Problem mit Pointer auf Structure


Autor: Jörn Mu (kitesurfing2006)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe ein Problem mit einer Struktur. Ich habe mir eine Struktur
angelegt die ich als lesemaske auf ein Array lege.

Funktioniert auch eigentlich nur mein Problem ist, das ich in der
struktur auch 16 bit breite variablen definiert habe. diese enthalten
dann nicht die richtigen Daten. solange die Variablen nur 8bit haben
funktioniert es einwandfrei. Ich arbeite mit Visual C++ 2005 Express.

Beispiel:

struct BootSector
{
unsigned __int8  BS_jmpBoot[3];    // 3 byte
unsigned __int8  BS_OEMName[8];    // 8 byte
unsigned __int16 BPB_BytesPerSec1;  // 2 byte
unsigned __int8  BPB_SecPerClus;  // 1 byte

};

void test(void)
{
  struct BootSector *BootSectorPointer; //Pointer auf struktur
  unsigned int test;

  BootSectorPointer= (struct BootSector *)init_buffer;
                                   //Strukturpointer die addresse des
                                   //buffers übergeben

  test = BootSectorPointer->BPB_BytesPerSec;
                                  //hier erhalte ich nun den falschen
                                    wert(0x0802) normal sollte es
                                    0x0200 sein
}

Im buffer stehen folgende werte:

Buffer = {EB, 3C, 90, 4D, 53, 44, 4F, 53, 35, 2E, 30, 00, 02, 08, 06,
00};

Hat jemand eine idee woran das liegen könnte??

MFG Jörn

Autor: Nico S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo kommt denn dein init_buffer her?
typedef struct BootSector
{
unsigned __int8  BS_jmpBoot[3];    // 3 byte
unsigned __int8  BS_OEMName[8];    // 8 byte
unsigned __int16 BPB_BytesPerSec1;  // 2 byte
unsigned __int8  BPB_SecPerClus;  // 1 byte

} BootSector_t;

void test(void)
{
 BootSector_t *BootSectorPointer;
 unsigned int test; // Wie wärs mit unsigned __int16?

  BootSectorPointer= (BootSector_t *)init_buffer;
                                   //Wo kommt der Init-Buffer her?

  test = BootSectorPointer->BPB_BytesPerSec;    
                                  //hier erhalte ich nun den falschen
                                    wert(0x0802) normal sollte es  
                                    0x0200 sein
}

Autor: Jörn Mu (kitesurfing2006)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh... also der init_Buffer ist ein pointer auf den Buffer der unten
angegeben ist und enthält

Buffer = {EB, 3C, 90, 4D, 53, 44, 4F, 53, 35, 2E, 30, 00, 02, 08, 06,
00};

diese werte...

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem liegt daran, daß sizeof (struct BootSector) eben nicht 14
ist.

Das hat mit dem sogenannten "alignment", der Ausrichtung von
Variablen im Speicher zu tun.

Microsoftspezifisch:

Kann mit #pragma pack(1) abgeschaltet werden.
Es empfiehlt sich, dieses nur für wirklich erforderliche Strukturen zu
tun, die genaue Sequenz sieht dann so aus:

  #pragma pack(push) // alte Einstellung aufheben
  #pragma pack(1)

  ... strukturdeklaration

  #pragma pack(pop)  // alte Einstellung wiederherstellen


Für andere Compiler ist gegebenenfalls deren Dokumentation nach dem
Schlüsselwort "alignment" zu durchsuchen.

Autor: Jörn Mu (kitesurfing2006)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

wow tausend Dank ;-) hab seit tagen daran rumgefummelt und dachte schon
ich wäre zu blöde, aber auf sowas wär ich nie gekommen. Jetzt kanns
endlich weitergehen.

weißt du zufällig auch wie dies beim WinAVR gemacht wird?

Jörn

Autor: neo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
16 bitter ?

byte-aligned structures benutzen!

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Compiler arbeitet korrekt du machst den Fehler!
Zum einen die Anordnung von 16/32bit etc Werten im Speicher ist
maschinenspezifisch. (MSB/LSB)
Solange du dem Compiler es nicht sagst wird er zur Optimierung die
Datenstrukturen aligned anordnen damit der Prozessor schneller
zugreifen kann.  Also z.B. an /2 oder /4 teilbare Adressen.
Das kannst du auch hervorragend an deinem Puffer nachvollziehen und du
bist gerade darüber gestolpert.
Einfachste Lösung: den Puffer Byteweise auslesen und Werte von Hand
zusammensetzen.
attribut packed

Autor: Marius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Das die member einer Struktur das kleinste alignment haben, kannst mit

__attribute__((_packed_)) machen.

z.B.
struct test_t {
     int  i0;
     char c0;
     int  i1;
} __attribute__((_packed_));

MfG
Marius

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.