qualified-id in declaration before '(' token



  • Ganz zum Schluß sollte es einen (wahrscheinlich sehr langen) Linkeraufruf geben, in welcher dann alle Objektfiles (.o) übergeben werden müssen - tauchen dort dann u.a. File.o, Map.o und auch NumericValue.o auf?

    Du solltest zumindestens den Compile- und Linkprozess verstehen, s. z.B. (in englisch) Introduction to the compiler, linker and libraries.



  • Du meinst diesen Bereich?

    |   LINK    output/UNIX/bin/xcsoar
    | rm output/data/icons/winpilot_reachable_160_alpha.png 
    output/data/icons/map_teammate_rgb.png 
    output/data/icons/map_taskturnpoint_alpha.png 
    output/data/icons/winpilot_marginal_160_rgb.png 
    output/data/icons/gps_lowsignal_160_rgb.png 
    output/data/icons/map_intersection_160_rgb.png 
    output/data/icons/map_ndb_160_rgb.png 
    output/data/icons/wrench_160_rgb.png 
    output/data/icons/map_tunnel_160_rgb.png 
    output/data/icons/map_target_rgb.png 
    output/data/icons/alt_marginal_airport_160_rgb.png 
    output/data/icons/map_small_160_alpha.png 
    output/data/icons/map_pgtakeoff_alpha.png 
    output/data/icons/map_reporting_point_160_alpha.png 
    output/data/icons/map_turnpoint_alpha.png 
    output/data/icons/gps_disconnected_rgb.png 
    output/data/icons/map_mountain_top_rgb.png 
    output/data/icons/map_intersection_160_alpha.png 
    output/data/icons/gps_lowsignal_rgb.png 
    output/data/icons/map_thermal_source_160_alpha.png 
    output/data/icons/alt_marginal_field_160_rgb.png 
    output/data/icons/flarm_alarm_alpha.png 
    output/data/icons/map_town_alpha.png output/data/
    ...
    gaaaaaaaaanz viele Zeilen
    ...
    
    | NOTE: make -j 4 HOSTCC=ccache gcc  HOSTCXX=ccache g++  AR=arm-
    ovlinux-linux-gnueabi-gcc-ar RANLIB=arm-ovlinux-linux-gnueabi-gcc-ranlib 
    CXX=ccache arm-ovlinux-linux-gnueabi-g++  -mthumb -mfpu=neon -mfloat-
    abi=hard -mcpu=cortex-a7 -fstack-protector-strong  -O2 -D_FORTIFY_SOURCE=2 
    -Wformat -Wformat-security -Werror=format-security --
    sysroot=/workdir/tmp/work/cortexa7t2hf-neon-ovlinux-linux-gnueabi/xcsoar-
    testing/git-r13/recipe-sysroot CC=ccache arm-ovlinux-linux-gnueabi-gcc  -
    mthumb -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 -fstack-protector-strong  
    -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-
    security --sysroot=/workdir/tmp/work/cortexa7t2hf-neon-ovlinux-linux-
    gnueabi/xcsoar-testing/git-r13/recipe-sysroot AS=arm-ovlinux-linux-gnueabi-as  
    LD=arm-ovlinux-linux-gnueabi-ld --sysroot=/workdir/tmp/work/cortexa7t2hf-
    neon-ovlinux-linux-gnueabi/xcsoar-testing/git-r13/recipe-sysroot  STRIP=arm-
    ovlinux-linux-gnueabi-strip CCACHE= DEBUG=n DEBUG_GLIBCXX=n 
    ENABLE_MESA_KMS=y GLES2=y GEOTIFF=n output/UNIX/bin/OpenVarioMenu
    |   CXX     output/UNIX/opt/src/Dialogs/ProcessDialog.o
    |   CXX     output/UNIX/opt/test/src/Fonts.o
    |   CXX     output/UNIX/opt/test/src/FakeLanguage.o
    |   CXX     output/UNIX/opt/test/src/FakeLogFile.o
    |   CXX     output/UNIX/opt/src/Kobo/FakeSymbols.o
    |   CXX     output/UNIX/opt/src/OV/OpenVarioMenu.o
    |   LINK    output/UNIX/bin/OpenVarioMenu
    

    Da kommt Map.o, File.o etc nicht vor



  • Dann mußt du diese noch zum passenden Makefile hinzufügen - das sollte dann build/ov.mk sein.

    Edit: Du mußt dann dort, wie bei den vorhandenen Zeilen, die Source-Dateien (.cpp) angeben.



  • Danke!!!!!!!! Das wars!



  • ein letztes kleines Problem bleibt.

    Diese Funktion

      static void ChangeConfigInt(const string &keyvalue, int value)
      {
        const Path ConfigPath("/boot/config.uEnv");
    
        ProfileMap configuration;
        Profile::LoadFile(configuration, ConfigPath);
        configuration.Set(keyvalue.c_str(), value);
        Profile::SaveFile(configuration, ConfigPath);
      }
    

    rufe ich so auf:

    ChangeConfigInt("rotation", 0);
    

    Der Eintrag sollte so aussehen:
    rotation=0

    er sieht aber so aus:
    rotation="0"

    Diese Funktion

      template<typename T>
      static void ChangeConfigString(const string &keyvalue, T value)
      {
        const Path ConfigPath("/boot/config.uEnv");
    
        ProfileMap configuration;
        Profile::LoadFile(configuration, ConfigPath);
        configuration.Set(keyvalue.c_str(), value);
        Profile::SaveFile(configuration, ConfigPath);
      }
    

    rufe ich so auf:

    ChangeConfigString("LANG", "en_EN.UTF-8");
    

    Der Eintrag sollte so aussehen:
    LANG =en_EN.UTF-8

    er sieht aber so aus:
    LANG ="en_EN.UTF-8"

    Wie kann ich dafür sorgen, dass die Anführungszeichen nicht eingetragen werden?



  • Das kannst (bzw. solltest) du direkt nicht ändern - die Funktion Write(const char *key, const char *value) in src/io/KeyValueFileWriter.cpp (welche von der Profile::SaveFile-Funktion aufgerufen wird), schreibt automatisch immer Anführungsstriche um den Wert herum:

    // write the value to the output file
    os.Format("%s=\"%s\"\n", key, value);
    

    Diese werden beim Einlesen von Read(KeyValuePair &pair) in src/io/KeyValueFileReader.cpp aber wieder herausgefiltert.



  • Das funktioniert bis auf einen Teil des Bootscreens, der interpretiert rotation="3" nicht und bleibt in der Standardausrichtung. Da muss ich mich mal auf die Suche machen, wie da ausgelesen wird, und muss versuchen das zu korrigieren.

    Der Teufel steckt mal wieder echt im Detail. Eine Datei, in die ich schreiben muss, existiert noch gar nicht. LoadFile macht dann Probleme. Ich muss also eine Überprüfung einbauen, ob die zu lesende Datei auch existiert.



  • Dieses Skript fragt die rotation für den erwähnten Teil des Bootscreens ab:

    #!/bin/sh
    
    # convert fbcon/rotate to degrees
    
    case "$(sed -n 's/^rotation=//p' /boot/config.uEnv)" in
    	"3")
    		rotation=90
    		;;
    	"2")
    		rotation=180
    		;;
    	"1")
    		rotation=270
    		;;
    	*)
    		rotation=0
    		;;
    esac
    exec /usr/bin/psplash --angle "${rotation}"
    

    Wenn in der /boot/config.uEnv rotation="3" steht, erhalte ich in der Shell mit "sed -n 's/^rotation=//p' /boot/config.uEnv"die Ausgabe "3". Ist dort rotation=3 eingetragen erhalte ich 3. 3 wird korrekt interpretiert, "3" nicht. Wie könnte ich das ändern, dass beides korrekt interpretiert wird??

    Update:
    die Zeile wie folgt geändert, löst das Problem:

    case "$(sed -n 's/^rotation=//p' /boot/config.uEnv | tr -d '"')" in
    


  • Wenn die Datei, in die geschrieben werden soll, noch nicht existiert, habe ich das mal zum Testen so gelöst:

      template<typename T>
      static void ChangeConfigString(const string &keyvalue, T value, const string &path)
      {
        const Path ConfigPath(path.c_str());
    
        ProfileMap configuration;
        Profile::SaveFile(configuration, ConfigPath);
        Profile::LoadFile(configuration, ConfigPath);
        configuration.Set(keyvalue.c_str(), value);
        Profile::SaveFile(configuration, ConfigPath);
      }
    

    die zusätzliche Zeile "Profile::SaveFile(configuration, ConfigPath);" einzufügen ist ja aber so noch keine saubere Lösung, da diese Zele nur ausgeführt werden sollte, wenn die Datei noch nicht existiert. Es müsste in etwa in der Weise formuliert werden:

      template<typename T>
      static void ChangeConfigString(const string &keyvalue, T value, const string &path)
      {
        const Path ConfigPath(path.c_str());
    
        ProfileMap configuration;
        if ("Datei ConfigPath existiert nicht")
        {
           Profile::SaveFile(configuration, ConfigPath);
        } 
        Profile::LoadFile(configuration, ConfigPath);
        configuration.Set(keyvalue.c_str(), value);
        Profile::SaveFile(configuration, ConfigPath);
      }
    

    Wie kann ich in der if-Abfrage denn überprüfen, ob die Datei existiert?



  • Du wirst wahrscheinlich eine Exception erhalten, wenn die Datei nicht existiert (oder andere Fehler beim Lesen auftreten), also fange sie

    try
    {
       Profile::LoadFile(configuration, ConfigPath);
    }
    catch (Exception &e)
    {
      // explicit do nothing
    }
    

    Es gibt wohl auch noch weitere IO-Funktionen z.B. in Open.hxx, aber selbst ein Überprüfen, ob die Datei existiert ist keine Garantie, daß diese auch gelesen werden kann!



  • noch mal herzlichen Dank!!!!

    Könnte man so den Wert von timeout auslesen?

      static void GetConfigInt(const string &keyvalue, int value, const string &path)
      {
        const Path ConfigPath(path.c_str());
    
        ProfileMap configuration;
        Profile::LoadFile(configuration, ConfigPath);
        configuration.Get(keyvalue.c_str(), value);
      }
    

    Aufrufen und interpretieren von timeoutvalue:

    GetConfigInt("timeout", timeoutvalue, "/boot/config.uEnv");
    unsigned remaining_seconds = timeoutvalue;
    




  • Sorry, ich seh nicht, wie das mit meinem Problem zu tun hat 😉



  • @Blaubart
    Du wolltest ein String-Value in ein Int umwandeln.



  • Nein, ich wollte einen Wert aus der Config auslesen und benutzen. Zumindest in meiner letzten Frage.



  • Du mußt dann auch den Parameter value als Referenz (&) übergeben (so wie bei ProfileMap::Get) - oder alternativ als Rückgabewert der Funktion.

    Wenn du jedoch mehrere Werte auslesen willst, dann wäre es besser nur einmalig die Datei zu laden und dann nur noch die ProfileMap direkt zu benutzen (also ProfileMap configuration als Klassenmember erstellen - so daß du dann keine eigene Funktion für jeden Datentyp mehr erstellen brauchst).



  • vielen Dank. Ich will tatsächlich nur einen Wert auslesen.
    Aber der Aufruf scheint nicht zu stimmen:

    GetConfigInt("timeout", timeoutvalue, "/boot/config.uEnv");
    
    | src/OV/OpenVarioMenu.cpp:1027:16: error: expected identifier before string constant
    |  1027 |   GetConfigInt("timeout", timeoutvalue, "/boot/config.uEnv");
    |       |                ^~~~~~~~~
    | src/OV/OpenVarioMenu.cpp:1027:16: error: expected ',' or '...' before string constant
    | src/OV/OpenVarioMenu.cpp:1027:3: error: ISO C++ forbids declaration of 'GetConfigInt' with no type [-fpermissive]
    |  1027 |   GetConfigInt("timeout", timeoutvalue, "/boot/config.uEnv");
    |       |   ^~~~~~~~~~~~
    | src/OV/OpenVarioMenu.cpp:52:15: warning: 'void GetConfigInt(const string&, int&, const string&)' defined but not used [-Wunused-function]
    |    52 |   static void GetConfigInt(const string &keyvalue, int &value, const string &path)
    |       |               ^~~~~~~~~~~~
    | make: *** [build/compile.mk:107: output/UNIX/opt/src/OV/OpenVarioMenu.o] Error 1
    | ERROR: oe_runmake failed
    


  • Steht der Aufruf innerhalb einer Funktion?

    C++ ist einfach zu komplex, um mal eben, ohne die Grundlagen genau zu kennen, ein (fehlerfreies) Programm zu schreiben. Ansonsten mußt du halt jede einzelne Fehlermeldung im Internet recherchieren (ganz zu schweigen von Laufzeitfehlern).

    Dein Eingangsbeitrag sowie weitere Nachfragen wurden ja beantwortet.



  • diese Funktion steht so am Anfang der Datei, wie auch ChangeConfigInt, welche ja funktioniert.
    https://github.com/freevariode/XCSoar/blob/master/src/OV/OpenVarioMenu.cpp

     static void GetConfigInt(const string &keyvalue, int value, const string &path)
      {
        const Path ConfigPath(path.c_str());
    
        ProfileMap configuration;
        Profile::LoadFile(configuration, ConfigPath);
        configuration.Get(keyvalue.c_str(), value);
      }
    

    Der Aufruf erfolgt hier:

    class MainMenuWidget final
      : public RowFormWidget
    {
      enum Controls {
        XCSOAR,
        LOGBOOK,
        FILE,
        SYSTEM,
        SHELL,
        REBOOT,
        SHUTDOWN,
        TIMER,
      };
    
      UI::Display &display;
      UI::EventQueue &event_queue;
    
      WndForm &dialog;
    
      UI::Timer timer{[this](){
        if (--remaining_seconds == 0) {
          HideRow(Controls::TIMER);
          StartXCSoar();
        } else {
          ScheduleTimer();
        }
      }};
    
      GetConfigInt("timeout", timeoutvalue, "/boot/config.uEnv");
      unsigned remaining_seconds = 3;
    
    public:
      MainMenuWidget(UI::Display &_display, UI::EventQueue &_event_queue,
                     WndForm &_dialog) noexcept
        :RowFormWidget(_dialog.GetLook()),
         display(_display), event_queue(_event_queue),
         dialog(_dialog) {}
    
    private:
      void StartXCSoar() noexcept {
        const UI::ScopeDropMaster drop_master{display};
        const UI::ScopeSuspendEventQueue suspend_event_queue{event_queue};
        Run("/usr/bin/xcsoar", "-fly");
      }
    
      void ScheduleTimer() noexcept {
        assert(remaining_seconds > 0);
    
        timer.Schedule(std::chrono::seconds{1});
    
        char buffer[256];
        snprintf(buffer, sizeof(buffer), "Starting XCSoar in %u seconds (press any key to cancel)",
                 remaining_seconds);
        SetText(Controls::TIMER, buffer);
      }
    
      void CancelTimer() noexcept {
        timer.Cancel();
        remaining_seconds = 0;
        HideRow(Controls::TIMER);
      }
    
      /* virtual methods from class Widget */
      void Prepare(ContainerWindow &parent,
                   const PixelRect &rc) noexcept override;
    
      void Show(const PixelRect &rc) noexcept override {
        RowFormWidget::Show(rc);
        if (remaining_seconds > 0)
          ScheduleTimer();
      }
    
      void Hide() noexcept override {
        CancelTimer();
        RowFormWidget::Hide();
      }
    
      bool KeyPress(unsigned key_code) noexcept override {
        CancelTimer();
        return RowFormWidget::KeyPress(key_code);
      }
    };
    
    


  • Innerhalb einer Klasse (oder Struktur) können nur Definitionen und Funktionen stehen, keine Anweisungen (wie z.B. ein Funktionsaufruf).
    Packe diese Codezeile in eine eigene Funktion und rufe sie von außerhalb auf, oder führe sie z.B. im Konstruktor MainMenuWidget(...) { /* hier einfügen */ } hinzu.

    Außerdem hast du timeoutvalue nirgendwo definiert -> das wird die nächste Fehlermeldung erzeugen...


Anmelden zum Antworten