AnsiString = AnsiString funktioniert nicht!?



  • Sorry, konnte nicht früher schreiben (Schule)

    OldMan00 schrieb:

    ich gehe mal davon aus, daß er den 6er meint, da er ja zu diesem Zeitpunkt geschrieben hatte, die 7er funktioniert bei ihm nicht und der 6er gefällt ihm bei weiten besser.

    Ja genau, benutze BCB 6, habe nun auch mit ShowMessage(Old); den String ausgegeben, das Fenster zeigt aber nichts an (also wie im Debugger angezeigt).

    Vielleicht mach ich ja einen Denkfehler

    Hier nochmal das Wichtigste meines Programms:

    const.h:

    AnsiString Symbol1; //gloable Deklaration
    

    Konstrukter der Form1:

    Symbol1 = "images\\circle.bmp"; //(relativer) Pfad des Bitmaps, welches standardmäßig geladen wird
    

    OnClick-Ereignis eines Images in der TChangeSymbol-Form:

    void __fastcall TChangeSymbol::Image4Click(TObject *Sender)
    {
            AnsiString Old;
            if(RadioButtonP1->Checked)
            {
                    //change symbol of player1
                    Old = Symbol1;
                    //change the old symbols to the new one:
                    change_symbols(Old,Symbol1);
            }
            //[...]
    }
    

    Nun der eigentliche Sinn ist es, dass der User das Bild, welches er als Logo haben will, auswählen kann. Im aktuellen Spiel sollte man das alte Spielfeld dann durch die neuen Symbole ersetzen, dadurch muss jedoch auch das alte Symbol bekannt sein (da nicht alles die gleichen Felder sind). Ja das wär's, ich weiß es gäbe auch andere Methoden, aber das hier ist wohl die einfachste, indem ich später die AnsiStrings Old und die gespeicherten im Spielfeld überprüfe und falls notwendig ersetze

    Ja es funktioniert leider nicht, ansonsten wird Old aber auch nirgends verändert!?

    Hilfe, Abgabetermin ist in einer Woche!



  • Hast Du in der Deklaration von TChangeSymbol noch ein zweites Symbol1?



  • witte_ schrieb:

    Hast Du in der Deklaration von TChangeSymbol noch ein zweites Symbol1?

    Nein auch nicht. Hab auch schon Symbol1 umbenannt (und natürlich überall wo es vorkam), zeigt aber immer noch denselben Fehler!



  • void __fastcall TChangeSymbol::Image4Click(TObject *Sender)
    {
            AnsiString Old;
            if(RadioButtonP1->Checked)
            {
                    //change symbol of player1
                    ShowMessage(Symbol1);
                    Old = Symbol1;
                    ShowMessage(Old);
                    //change the old symbols to the new one:
                    change_symbols(Old,Symbol1);
            }
            //[...]
    }
    

    Was gibt dir dieser Quelltext in der ersten bzw. zweiten Box aus?



  • OK, habs jetzt endlich fertig!

    Ich weiß nicht genau an was es lag, hab mehrere Änderungen durchgenommen:
    - Include-Guards (bei den Konstanten) hinzugefügt
    - aus konstanten AnsiStrings variable gemacht (werden natürlich nicht verändert)
    das hat nämlich immer zu Linker-Errors geführt 😮 (Einbindung der Variablen in der Header mittels extern

    Nochmal durch Debuggt und plötzlich ging die Zuweisung 😮
    Wahrscheinlich lag es an den nicht vorhandenen Include-Guards (achtet immer auf die Linker-Warnungen)

    Auf jedenfall funktioniert es nun 🙂



  • Das ist halt das Problem mit globalen Variablen. Da tauche derartige Dreckeffekte immer mal wieder auf. Eigentlich ist das ein deutliches zeichen dafür sein Design zu überdenken. 🙂



  • Braunstein schrieb:

    Das ist halt das Problem mit globalen Variablen. Da tauche derartige Dreckeffekte immer mal wieder auf. Eigentlich ist das ein deutliches zeichen dafür sein Design zu überdenken. 🙂

    Ja aber gehört es auch zum guten Programmierstil seine Konstanten nicht global zu definieren? Ich meine hier sind nicht alles Konstanten okay versteh ich, im nächsten Projekt werde ich das anders machen. Aber wenn die Konstanten von (fast) allen Forms gebraucht werden, sollte man dann auch nicht global deklarieren?



  • Bei Konstanten kann man das schon so machen. Ich bevorzuge hier aber eher eine struct in der alle diese Konstanten zusammengefasst werden. Die lege ich dann in einen Singleton ab.
    Bei performancekritischen Programmteilen arbeite ich aber auch mit extern.
    Ich hatte hier irgendwie nicht gesehen, dass es sich um globale Konstanten handeln soll (kein const).



  • Braunstein schrieb:

    Bei Konstanten kann man das schon so machen. Ich bevorzuge hier aber eher eine struct in der alle diese Konstanten zusammengefasst werden. Die lege ich dann in einen Singleton ab.
    Bei performancekritischen Programmteilen arbeite ich aber auch mit extern.
    Ich hatte hier irgendwie nicht gesehen, dass es sich um globale Konstanten handeln soll (kein const).

    Es waren auch nicht alle global (z.B. Symbol, Symbol2), aber z.B. triangle,cross,... waren globale AnsiStrings. Diese habe ich früher auch als konstant (const) deklariert, durch das extern wollte mir der Linker das aber nie abnehmen (auch wenn ich extern const AnsiString... schrieb). Er brachte immer eine Linker-Error z.B. Undefined Symbol _triangle (mit Unterstrich). Ich habe nun zu Testzwecken das const entfernt und da nur ich an diesem Projekt arbeite, auch darauf geachtet sei nirgends zu verändern (ich weiß, kein guter Programmierstil, aber wenn der Linker nicht mitspielt)



  • extern const AnsiString ist kein Problem. Wenn dein Linker da nicht mitspielt hast du was anderes falschgemacht.



  • Braunstein schrieb:

    extern const AnsiString ist kein Problem. Wenn dein Linker da nicht mitspielt hast du was anderes falschgemacht.

    Ja aber wenn ich sie nicht konstant deklariere funktioniert alles, wenn ich alles auf const umändere:
    const.h:

    const AnsiString triangle = "images\\triangle.bmp";
    

    Unit2.cpp:

    extern const AnsiString triangle;
    

    Das führt zu folgendem Linkererror:

    [Linker Fehler] Unresolved external '_triangle' referenced from K:\TICITACTOE\TICITACI6\UNIT2.OBJ
    

    da ist wohl ansonsten nichts falsch, oder schon? Ach ja, const.h wird in Unit1.h inkludiert, ebenso Unit2.h



  • Du machst es ja auch genau verkehrt rum. Das

    extern const AnsiString triangle;
    

    gehört in den Header und die Definition in eine cpp.



  • Braunstein schrieb:

    Du machst es ja auch genau verkehrt rum. Das

    extern const AnsiString triangle;
    

    gehört in den Header und die Definition in eine cpp.

    Ja aber ich definiere die AnsiStrings in meinem Header const.h, wo sie ihren (konstanten) "Wert" zugewiesen bekommen. Somit ist das praktisch einfach eine normale Header-Datei.
    Aus der Unit1 rufe ich dann die Unit2 auf, in welcher ich nun mittels extern diese AnsiStrings "einbinde". Wenn ich die extern-Deklaration in den Header der Unit2 schiebe, bleibt es bei den selben Linker Errors.



  • Hallo

    Braunstein hat schon recht. Probier es doch einfach mal aus.

    bis bald
    akari





  • Ich glaube ich steh gerade auf der Leitung

    In meinem Buch steht:

    The extern specifier tells the compiler that the following
    variable types and names have been declared elsewhere. In other words, extern lets the compiler know what the types and names are for these global variables without
    actually creating storage for them again. When the two modules are linked, all
    references to the external variables are resolved.
    

    Braunstein schrieb:

    Du machst es ja auch genau verkehrt rum. Das

    extern const AnsiString triangle;
    

    gehört in den Header und die Definition in eine cpp.

    Ich habe nun auch versucht die extern-Deklarationen in die Unit2.h zu packen mit demselben Ergebnis. Die Definition meiner AnsiStrings findet in der const.h statt, sollte ich das nun in eine cpp umwandeln? -Wie gesagt, ich steh gerade auf der Leitung



  • Nein. extern sagt dem Compiler, dass eine Variable dieses Namens existiert und irgendwo auch definiert wird. Damit die Variable in deinem Programm bekannt gemacht werden kann, packst diese extern Deklaration in einen Header.
    Die dazu gehörige Definition packst du in irgendeine cpp damit der Linker sie auch findet.



  • Hallo

    Also nochmal...

    const.h:

    #ifndef CONST_H
    #ifndef CONST_H
    
    #include <vcl.h> // Muß mit rein
    
    extern const AnsiString triangle;
    
    #endif
    

    const.cpp:

    #include "const.h"
    
    const AnsiString triangle = "images\\triangle.bmp";
    

    Unit2.h

    #include "const.h"
    // ... hier triangle benutzen
    

    bis bald
    akari

    /Edit : Code korrigiert



  • Diese sch*** Leitungen immer 🙂
    Danke für eure Erklärungen, habe sie genauestens befolgt, bekomme nun aber dutzende Compiler-Fehler, an welchen ich schon seit einer halben Stunde ratlos davor sitze:
    z.B.

    [C++ Fehler] const.h(5): E2141 Fehler in der Deklarationssyntax
    Das zeigt er bei dieser Zeile an:
    extern const AnsiString white; //bzw auch bei triangle usw.
    
    Oder dieser hier:
    [C++ Fehler] const.h(11): E2238 Bezeichner 'AnsiString' mehrfach deklariert
    in diser Zeile hier extern AnsiString Symbol;    //Symbol user 1
    

    Ich versteh einfach nicht was an dieser Deklaration falsch sein soll, definiert wird white in const.cpp wie oben schon von akari beschrieben:

    const AnsiString white = "images\\white.bmp";
    

    Aber ich glaube ohne Quelltext wird es für euch schwer sein einen Fehler zu finden 😞 , ansonsten hab ich jedoch nichts geändert!



  • Hallo

    Wie mans auch macht...
    Es fehlt noch der include für die VCL, damit der Compiler den Typ AnsiString kennt. Hab meinen Code korriert.

    bis bald
    akari


Anmelden zum Antworten