Kann nicht auf member eines union zugreiffen



  • Hallo,

    Nur als Warnung: ich programmiere noch nicht sehr lange Qt/C++ und es kann sein dass einigen diese Frage nun mit *face-palm* beantworten 😃

    Wie dem auch sei:

    Ich habe folgendes struct:

    struct SysRequestT
        {
            unsigned short reqAccept;
            unsigned short sysOpCode;
            union
            {
                struct
                {
                    int closeCompl;
                }SysCloseT;
    
                struct
                {
                    int diagnostic;
                    int newState;
                    int changeCompl;
                    int errSlavWrd;
                }SysChangeStateT;
    
                struct
                {
                    int switchOnOff;
                    int switchCompl;
                }SysWarningLampT;
    
                struct
                {
                    SysConfigDataT *SysConfigData;
                }SysConfigT;
    
                struct
                {
                    int sysAnalzState;
                }SysIdleT;
            }Values;
        };
    

    Weiter habe ich einen QTcpSocket namens con.
    Da mir dieser nur ein char Array übergeben kann muss ich dieses irgendwie in mein struct bekommen (welches ich als msg deklariert habe) und habe es wie folgt gelöst:

    int bytesAvailable = con->bytesAvailable();
            char buf[bytesAvailable];
            int read_ret =  con->read(buf, con->bytesAvailable());
            memcpy(&msg,buf,bytesAvailable);
    

    nun habe ich jedoch das Problem dass z.B. der Aufruf msg.SysConfigData mit dem Fehler

    'struct sysdef::SysRequestT' has no member named 'SysConfigData'

    beim Kompilieren endet...was mache ich hier falsch?



  • msg.Values.SysConfigData



  • Fellhuhn schrieb:

    msg.Values.SysConfigData

    Danke, habe ich auch schon probiert und ändert leider nichts 😞



  • Es gibt auch in deine Values-Union kein Element namens SysConfigData. Wenn, dann probier doch mal das:
    msg.Values.SysConfigT.SysConfigData

    Deine Struktur sieht übrigens etwas seltsam aus: Kennst du dich mit Unions aus und weißt, was du da tust? Jede der Unter-Strukturen liegt im selben Speicherbereich, die ints closeCompl und diagnostic z.B. sollten dir den gleichen Wert liefern und sich gegenseitig überschreiben.

    Ich habe auch mal für Netzwerk-Code eine Union gebraucht, die sich mit einem char * überlagert, das sähe dann in etwa so aus:

    union
    {     struct
          {      
                struct 
                { 
                   int closeCompl; 
                }SysCloseT; 
    
                struct 
                { 
                    int diagnostic; 
                    int newState; 
                    int changeCompl; 
                    int errSlavWrd; 
                }SysChangeStateT; 
    
                struct 
                { 
                    int switchOnOff; 
                    int switchCompl; 
                }SysWarningLampT; 
    
                struct 
                { 
                    SysConfigDataT *SysConfigData; 
                }SysConfigT; 
    
                struct 
                { 
                    int sysAnalzState; 
                }SysIdleT;
        }OberStruktur;
        char Ueberlagerung[5000];
    }
    

    So überlagern sich die einzelnen Strukturen nicht mehr. Alternativ könntest du auch einfach den Pointer auf "Oberstruktur" hin und herkonvertieren, dann sparst du dir die ganze Union.



  • Kennst du dich mit Unions aus

    Ich kenne mich soweit aus dass es anscheinend nur möglich sein soll dass ein Inhalt vom union genutzt wird. Zumindest steht das bei MSDN (http://msdn.microsoft.com/en-us/library/5dxy4b7b(VS.80).aspx) so drin ("A union is a user-defined data or class type that, at any given time, contains only one object from its list of members") und C++.NET sollte sich in dieser Beziehung nicht all zu weit unterscheiden.

    Der Fehler dass es nicht verfügbar ist kommt jetzt nicht mehr (auch wenn die Qt IDE mir eigentlich immer msg.SysConfigData vorgeschlagen hat) und es existiert nur noch ein conversion Fehler.

    Ich bedanke mich hier einmal und muss nach dem Mittagessen mal schauen woher dieser neue Fehler kommt (was jedoch einfacher sein wird)...



  • Danke 🙂

    Geht nun alles auch wenn ich mangels wissen über das was ich da per TcpSocket eigentlich bekomme keine Ahnung habe ob es wirklich geht aber das ist ein internes Problem 🙄



  • So habe mich mal registriert um nicht bei jedem Mal wo ich den alten Beitrag editieren will einen neuen machen muss.

    Du hast vorhin etwas von überschreiben geschrieben. Ist es nicht die Idee eines union dass es immer nur einen der member nutzt oder habe ich da jetzt etwas falsch verstanden?



  • bluefisch200 schrieb:

    Du hast vorhin etwas von überschreiben geschrieben. Ist es nicht die Idee eines union dass es immer nur einen der member nutzt oder habe ich da jetzt etwas falsch verstanden?

    Du kannst immer nur einen Member einer Union nutzen. Und alle nutzen den gleichen Speicherbereich. Aber es gibt keinen Weg für den Compiler festzustellen, welcher der gerade gültige Member ist. Du kannst also beliebigen Blödsinn machen.

    Noch eine Warnung: Du verschickst die Roh-Daten einer Struktur. Da musst du aufpassen. Verschiedene Compiler legen diese verschieden an. Bzw. die Endianess kann unterschiedlich sein. Wenn dein Programm auf verschiedenen Rechnern läuft und mit verschiedenen Compilern übersetzt wurde, kann es sein, dass nicht das richtige ankommt.

    Wenn deine struct virtuelle Member hat, dann würdest du ebenfalls die vtable mit schicken. Und das ist gar keine so gute Idee.

    Wenn du also weißt, was du tust, ist alles gut. Sei nur gewarnt, dass das alles nicht so ganz "ungefährlich" ist.

    Wenn du magst, kannst du dich mal mit "serialization" auseinandersetzen. Gibt z.B. eine recht nette Bibliothek von Boost dazu.



  • Ich nehme mal an dass der Qt Creator auf allen Plattformen den selben Compiler einsetzt.

    Eine andere Frage, wie kann ich herausfinden wie gross dass eine Variable dieses structs ist? Ein union nimmt ja immer das Minimum das möglich ist also sollte es mit einem sizeof ja eigentlich nicht gehen...



  • bluefisch200 schrieb:

    Eine andere Frage, wie kann ich herausfinden wie gross dass eine Variable dieses structs ist? Ein union nimmt ja immer das Minimum das möglich ist also sollte es mit einem sizeof ja eigentlich nicht gehen...

    sizeof sollte deine Zwecke erfüllen, egal ob du nun sizeof(int) oder sizeof(SysWarningLampT) oder so nimmst - nur der (char 😉 könnte dir ein paar Probleme machen, da das ja mehr oder weniger ein int ist, die Daten dahinter liegen an anderer Stelle.



  • bluefisch200 schrieb:

    Ich nehme mal an dass der Qt Creator auf allen Plattformen den selben Compiler einsetzt.

    Nein tut er nicht. Außerdem bekommst du immer noch Probleme mit der Endianess, wenn du es so machst.

    Das funktioniert sicher nur bei: Gleicher Compiler, gleiches Betriebssystem und gleiche Prozessorarchitektur.


Anmelden zum Antworten