Problem mit union



  • Weil du ihn doppelt verwendet hast - einmal als typedef für "unsigned char[50]" und einmal als Element der Union.

    Sehe ich ein.

    union 
    {
           struct
           {
                unsigned int a;
                unsigned int b;
           }Values;
    
           struct
           {
                unsigned char TXBuffer[50];
    
           }Buffer;         
    }TxData;
    
    TXData.Values.a = 0x1234;
    TXData.Values.b = 0x5678;
    

    Nun steht in TXData.Buffer.TXBuffer[0] = 34, [1] = 12, [2] = 78, [3] = 56.
    Denn Bufferinhalt sende ich nun via Rs232 zu einem Controller, der folgende
    union hat

    union 
    {
           struct
           {
                unsigned int a;
                unsigned int b;
           }Values;
    
           struct
           {
                unsigned char RXBuffer[50];
    
           }Buffer;         
    }RxData;
    

    nach RxData.Buffer.RxBuffer .

    Nun stehen in RxData.Values.a = 0x1234 , ...b = 5678.
    Ich erspare mir damit das lästige umkopieren der Values in die Buffer.



  • Und an welcher Stelle hast du nun deine Probleme? Am Ende steht das in den Rx... Elementen, was du vorne in Tx... eingetragen hast.

    (btw kannst du Probleme bekommen, wenn du beide Teile auf verschiedenen Systemen laufen hast - der C++ Standard schreibt nicht vor, wie (z.B.) ein unsigned int aufgebaut ist)

    PS: Was ich noch verbessern würde: gib der union einen Namen und pack sie in einen gemeinsam verwendeten Header 😉

    //defs.h
    union MsgData
    {
      //...
    };
    
    //Tx.cpp
    #include "defs.h"
    MsgData TxData;
    
    //Rx.cpp
    #include "defs.h"
    MsgData RxData;
    


  • typedef unsigned char BUFFER[50];
    typedef union
    {
        struct
        {
              unsigned char ClearTestStatus        :1;  // 1 Done
        }bits;
        unsigned char byte;
    
    }RESETTESTMODE;
    union
    {
        struct
        {
                     unsigned int          SN;
                     unsigned int          Dummy;   //Hier muss ich ein Dummy          
            RESETTESTMODE ResetTestMode;     //einfügen
        }Values;
         struct
         {
                BUFFER TXBuffer;
        }Buffer;
    }TxData;
    

    Das mit dem BUFFER sollte so ausehen.



  • Und wo ist das Problem? in der Union stehen "parallel" zueinander eine struct mit drei Elementen (das letzte ist wieder eine union) und dein char-Buffer - wobei die Verteilung der struct-Bytes in den Puffer-Bereich willkürlich vom Compiler/Prozessor/was-weiß-ich vorgenommen werden kann.



  • (btw kannst du Probleme bekommen, wenn du beide Teile auf verschiedenen Systemen laufen hast - der C++ Standard schreibt nicht vor, wie (z.B.) ein unsigned int aufgebaut ist)

    Da das eine auf dem PC 80x86 läuft ist hier ein int natürlich 32 bit breit, es muss
    natürlich unsigned short(16Bit) sein, ein Schreibfehler von mir,

    union
    {
           struct
           {
                unsigned short a;
                unsigned short b;
           }Values;
    
           struct
           {
                unsigned char TXBuffer[50];
    
           }Buffer;        
    }TxData;
    
    TXData.Values.a = 0x1234;
    TXData.Values.b = 0x5678;
    

    Da die zweite Union sich in einem 8Bit Controller
    befindet

    union
    {
           struct
           {
                unsigned int a;
                unsigned int b;
           }Values;
    
           struct
           {
                unsigned char RXBuffer[50];
    
           }Buffer;        
    }RxData;
    

    ist hier int natürlich 16bit breit.

    wobei die Verteilung der struct-Bytes in den Puffer-Bereich willkürlich vom Compiler/Prozessor/was-weiß-ich vorgenommen werden kann.

    Wie mir bekann ist stehen die MemberVariablen in einer struct immer der
    Reihe nach im speicher.
    Ich habe diese frage schon einmal gestellt, es wurde behauptet das dieses
    bei jedem Compiler so ist.
    Na ja bei dem C++ Bilder sowie den Compiler für den µC ist es jedenfalls
    so(im Watch Fenster überprüft).

    Auf jedenfall funktioniert das ganze so wie ich es gemacht habe.



  • Die Elemente stehen hintereinander im Speicher - aber dazu kommen noch Probleme wie Padding (der Compiler darf Zwischenräume lassen) und big endian vs little endian (Bedeutung der Bits in einem int).



  • Ok, also für mich war(ist) eine Union für meinen Zweck bestens geeigned.
    Da es aufgrund dieser Tatsache nicht auf jedem Compiler so läuft, frage
    ich mich wofür dann so eine Union da ist.

    Gebe mal ein praktisches Beispiel.



  • hermes schrieb:

    Da es aufgrund dieser Tatsache nicht auf jedem Compiler so läuft, frage
    ich mich wofür dann so eine Union da ist.

    Meinen Post gelesen? 😉



  • Eine Union ist dazu da, Speicher zu sparen. Man soll bei einer union nur auf das ??? zuletzt zugewiesene Feld zugreifen.?????

    Verstehe ich nicht ganz, kannst du das mal genauer erklären.



  • Eine besondere Typkonstruktion ist die union. Man könnte sie als Entweder-oder-Verbund bezeichnen. In einer Union werden mehrere Variablen zusammengefasst, von denen nur eine gebraucht wird. Es kann also immer nur eines der angegebenen Elemente verwendet werden. Eine Union nimmt darum so viel Speicher ein, wie das größte seiner Elemente benötigt.

    Ok ist schon klar, hast du nicht einen Vorschlag wie man das was ich möchte
    anders hinbekommt?


Anmelden zum Antworten