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
Wo kommt denn dein init_buffer her?
1 | typedef struct BootSector |
2 | {
|
3 | unsigned __int8 BS_jmpBoot[3]; // 3 byte |
4 | unsigned __int8 BS_OEMName[8]; // 8 byte |
5 | unsigned __int16 BPB_BytesPerSec1; // 2 byte |
6 | unsigned __int8 BPB_SecPerClus; // 1 byte |
7 | |
8 | } BootSector_t; |
9 | |
10 | void test(void) |
11 | {
|
12 | BootSector_t *BootSectorPointer; |
13 | unsigned int test; // Wie wärs mit unsigned __int16? |
14 | |
15 | BootSectorPointer= (BootSector_t *)init_buffer; |
16 | //Wo kommt der Init-Buffer her?
|
17 | |
18 | test = BootSectorPointer->BPB_BytesPerSec; |
19 | //hier erhalte ich nun den falschen
|
20 | wert(0x0802) normal sollte es |
21 | 0x0200 sein |
22 | }
|
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...
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.
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
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
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
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.