Auf bestimmte Position einer Struktur zugreifen (Bitmuster)



  • Moin Mahlzeit,

    bin gerade dabei ein kleines MFC (dialogbasierend) Programm zur Darstellung von Messwerten zu erstellen.

    Grob erklärt: es geht um einen seriellen Bus, von welchem ich 64 Bit einlese und in eine Struktur (raw) ablege:

    typedef union {
    	struct {
    		short int reserved;		// to fill up to 64bit
    		short int i16Value1;
    		short int i16Value2;
    		short int i16Value3;
    	};
    	unsigned long long raw;
    } telegram1;
    

    Bei diesem Beispiel funktioniert die Aufteilung der 64Bit in die gewünschten 4x16 Bit ohne Probleme, und ich erhalte das erwartete Bitmuster von z.B. i16Value1 beim lesen.

    Probleme habe ich allerdings mit z.B. folgender Struktur:

    typedef union {
    	struct {
    		byte reserved4;				// to fill up to 64bit
    		unsigned int error_flags;
    		unsigned short int i16Reserved;		// to fill up to 64bit
    		unsigned char i8Reserved;		// to fill up to 64bit
    	};
    	unsigned long long raw;
    } telegram2;
    

    Hier verschiebt sich das Bitmuster irgendwie. Also selbst wenn ich raw mit 0 beschreibe, stehen beim lesen von i16Reserved und i8Reserved Werte drin (52428 und 204).

    Die Anordnung der Strukturmember ist dem Aufbau des Telegramms für den seriellen Bus entsprechend.

    Also zur Frage: Übersehe ich etwas beim aufteilen der 64 Bit innerhalb der Struktur, bzw. gibt es da überhaupt den von mir erkannten zusammenhang (die zuerst angelegte Variable steht an hinterster Stelle / LSB).

    Besten Dank, MfG



  • Geht es so ?

    #pragma pack(push, 1)
    typedef union {
        struct {
            byte reserved4;            
            unsigned int error_flags;
            unsigned short int i16Reserved;    
            unsigned char i8Reserved;       
        };
        unsigned long long raw;
    } telegram2;
    #pragma pack(pop)
    


  • ähhh... Ja! Danke!

    Könntest du mir bitte erklären, wieso es funktionier, bzw. was es damit auf sich hat? push und pop verbinde ich mit Assembler und sehe hier irgendwie keinen Zusammenhang.

    Vielen Dank schonmal 😉



  • Du uebersiehst padding.



  • Vereinfacht gesagt: Es ist für Prozessoren sehr ineffizient auf Strukturelemente zuzugreifen, die "ein Byte versetzt" sind. Deswegen darf der Compiler da Füllbytes einfügen, was mit #pragma pack(1) verhindert wird. Das push und pop dienen nur dazu, dass er sich die alte Einstellung merkt und nach dem Union wieder herstellt.



  • Ergibt Sinn.

    Vielen Dank nochmal.

    Ich nehme also an, dass knivil damit meinte, ich übersähe das Padding des Compilers. So schließt sich der Kreis.



  • KPY3EP schrieb:

    ähhh... Ja! Danke!

    Könntest du mir bitte erklären (...)

    Hilfe zur Selbsthilfe:

    1. F1
    v---------------- Cursor hier platzieren und F1 drücken
    #pragma pack(push, 1)
    typedef union {
        struct {
           // ...
    

    Falls das nicht zum gewünschten Ergebnis führt:

    1. Google

Anmelden zum Antworten