Dos.h funzt net :(



  • Naja ich dachte dadurch an folgende funktion:

    void wait::Start()
    {
        #ifdef __Windows
        Sleep(Time);
        #ifdef __linux__
        // Code
        #ifdef __unix__
        // Code
        #endif
    }
    

    Heißt die Funktion unter den anderen Systemen auch Sleep()?
    Ja oder?^^



  • Wikinger75 schrieb:

    Naja ich dachte dadurch an folgende funktion:

    void wait::Start()
    {
        #ifdef __Windows
        Sleep(Time);
        #ifdef __linux__
        // Code
        #ifdef __unix__
        // Code
        #endif
    }
    

    Heißt die Funktion unter den anderen Systemen auch Sleep()?
    Ja oder?^^

    Schau selber nach unistd.h.

    Und warum so kompliziert? So weit kommst du doch gar nicht du musst ja schon beim Inkludieren der Header wissen welche Betriebssystem verwendet wird und dann vereinfacht sich der Code zu

    #ifdef __Windows // oder wie auch immer
       Sleep(abit);
    #elif defined(_POSIX_VERSION)
       sleep(abit);
    #else
    #  error "Unsupported platform."
    #endif
    

    Der Code funktioniert so übrigens nicht, da sleep in Sekunden arbeitet. Aber es gibt unzählige andere Sleep-Funktionen in unistd.h, schau einfach mal bei obigem Link (am besten die Doku von sleep aufrufen dort findest du die anderen Versionen aufgelistet).



  • So hab jetzt folgende Code, der Systemunabhängig laufen müsste:

    // Wait.hpp
    /* Doppeltes einbinden verhindern! */
    #ifndef WAIT_HPP_
    #define WAIT_HPP_
    
    /* Benötigte Header */
    #include <windows.h> // Windows!
    #include <unistd.h> // Linux, Mac OS & UNIX!
    
    class wait
    {
    private:
        int *Time;
    public:
        wait();
        wait(int Time);
        ~wait();
        int getTime() const;
        void setTime(int Time);
        void setTimeNULL();
        void Start();
    };
    
    //----------> Konstruktoren <----------//
    wait::wait()
    {
        this->Time = new int;
    }
    
    wait::wait(int Time)
    {
        this->Time = new int;
        this->Time = Time;
    }
    
    //----------> Destruktoren <----------//
    wait::~wait()
    {
        delete this->Time;
    }
    
    //----------> Getter <----------//
    int wait::getTime() const
    {
        return this->Time;
    }
    
    //----------> Setter <----------//
    void wait::setTime(int Time)
    {
        this->Time = Time;
    }
    
    void wait::setTimeNULL()
    {
        this->Time = 0;
    }
    
    //----------> Andere <----------//
    void wait::Start()
    {
        /* Funktion soll Systemunabhängig sein! */
        #ifdef __Windows
        Sleep(Time);
        #elif defined(_POSIX_VERSION)
        sleep(Time);
        #else
        #  error "Unsupported platform."
        #endif
    }
    
    //---------->> ENDE <<----------//
    
    #endif
    

    Das wäre jetzt z.b eine Unabhängige Klasse oder?



  • Nein, denn windows.h gibt es nur im Platform SDK von Microsoft Windows und somit sieht ein Kompileraufruf unter Linux ungefähr so aus:

    $ g++ test.cpp -o test
    test.cpp:7:34: error: windows.h: No such file or directory
    test.cpp: In constructor ‘wait::wait(int)’:
    test.cpp:33: error: invalid conversion from ‘int’ to ‘int*’
    test.cpp: In member function ‘int wait::getTime() const’:
    test.cpp:45: error: invalid conversion from ‘int* const’ to ‘int’
    test.cpp: In member function ‘void wait::setTime(int)’:
    test.cpp:51: error: invalid conversion from ‘int’ to ‘int*’
    test.cpp: In member function ‘void wait::Start()’:
    test.cpp:66: error: invalid conversion from ‘int*’ to ‘unsigned int’
    test.cpp:66: error: initializing argument 1 of ‘unsigned int sleep(unsigned int)’

    Du musst schon um die Inkludes ein #ifdef-Block packen der den passenden Header findet je nach verwendetem System. Schaut dir mal autoconf an damit kannst du eine Datei erstellen bzw. ein Skript welches man vorm Kompilieren aufruft dieses überprüft bestimmte Eigenschaften (zum Beispiel vorhandene Bibliotheken, die genutzte Plattform, Betriebssystem, uvm.) und stellt das bereit, so dass deine Anwendung beim Kompilieren weiß womit sie es zu tun hat.



  • /* Benötigte Header */
    #ifdef __Windows
       #include <windows.h> // Windows!
    #else
       #include <unistd.h> // Linux, Mac OS & UNIX!
    #endif
    

    Damit müsste es Funktionieren...

    Thx für die Seite, die schau ich mir noch irgentwan mal in ruhe an^^



  • 1. war der pointer doof und damit die Aufrufe falsch, weil Sleep keinen Pointer sondern den Wert möchte - d.h. deine klasse (es hätte zwar auch ne Fkt getan, aber ok...) hat die adresse in einen int umgewandelt und so lange gesleept...
    2. wozu eine fkt, wie SetTimeNULL?
    3. gibt es Initialisierungslisten
    4. teilt man idr. zwischen *.h und *.cpp auf - *.hpp ist nicht so üblich, aber ich habs mal so gelassen... da man das so schön aufteilt, hat man jz die *.h schön zum mal schnell nachgucken, was gemacht wird und die *.cpp muss man nie wieder angucken - die includes werden somit auch in die *.cpp verschoben, weil du die net brauchst
    5. ist es doch hässlich, jedes mal wieder this-> vor member zu schreiben - und unnötig
    6. wie gesagt, funzt das mit dem immer includen nicht so richtig - hab ich auch mal geändert
    7. will die sleep-fkt sekunden haben und die Sleep arbeitet mit millisekunden... damit ist auch die bezeichnung time doof - aber bissl was sollst du ja auch noch zu tun haben ^^

    // Wait.hpp 
    /* Doppeltes einbinden verhindern! */ 
    #ifndef WAIT_HPP_ 
    #define WAIT_HPP_ 
    
    class wait 
    { 
    private: 
        int time;
    public: 
        wait(); 
        wait(int _time);
        int getTime() const    { return time; }
        void setTime(int _time){ time = _time; }
        void Start();
    };
    
    #endif
    
    /*wait.cpp*/
    #include "wait.hpp"
    
    wait::wait() : time(0)
    {} 
    
    wait::wait(int _time) : time (_time)
    {}
    
    void wait::Start() 
    {
        #ifdef __Windows
          #include <windows.h>
          Sleep(time);
        #elif defined(_POSIX_VERSION) 
          #include <unistd.h>
          sleep(time/1000); 
        #else
          #error Not a supported platform
        #endif 
    }
    

    falls du fragen hast, dann frag...

    bb



  • Ja klar ist das falsch, das hab ich nur mal so runtergekritzelt und später in ruhe überarbeitet. Momentan sieht das ganze so aus:

    // Timer.hpp
    
    #ifndef TIMER_HPP_
    #define TIMER_HPP_
    
    /* Benötigte Header */
    #ifdef __WIN32__
       #include <windows.h> // Windows!
    #else
       #include <unistd.h> // Linux, Mac OS & UNIX!
    #endif
    
    class Timer
    {
    private:
        int Time;
    public:
        Timer();
        Timer(int Time);
        ~Timer();
        int getTime() const;
        void setTime(int Time);
        void setTimeNULL();
        void Start();
    };
    
    //----------> Konstruktoren <----------//
    Timer::Timer()
    {
    }
    
    Timer::Timer(int Time)
    {
        this->Time = Time;
    }
    
    //----------> Destruktoren <----------//
    Timer::~Timer()
    {
    }
    
    //----------> Getter <----------//
    int Timer::getTime() const
    {
        return this->Time;
    }
    
    //----------> Setter <----------//
    void Timer::setTime(int Time)
    {
        this->Time = Time;
    }
    
    void Timer::setTimeNULL()
    {
        this->Time = 0;
    }
    
    //----------> Andere <----------//
    void Timer::Start()
    {
        /* Funktion soll Systemunabhängig sein! */
        #ifdef __WIN32__
           Sleep(this->Time);
        #elif defined(_POSIX_VERSION)
           sleep(this->Time);
        #else
           #error "Unsupported platform."
        #endif
    }
    
    //---------->> ENDE <<----------//
    
    #endif
    

    Dieser Code ist schon ausführbar...

    4. teilt man idr. zwischen *.h und *.cpp auf - *.hpp ist nicht so üblich, aber ich habs mal so gelassen... da man das so schön aufteilt, hat man jz die *.h schön zum mal schnell nachgucken, was gemacht wird und die *.cpp muss man nie wieder angucken - die includes werden somit auch in die *.cpp verschoben, weil du die net brauchst

    Na klar teile ich die auf, aber Leute die das Kopieren könnens selber aufteilen :p . Ich finde das lesserlich in einer Datei besser (Fürs Forum).
    Außer der Code ist lang dan sollte man schon aufgeteilt Posten...

    Mfg Wikinger75!



  • du hast offenbar noch immer nicht bemerkt, dass #error keine "" braucht...

    gut - damit bleiben nur noch 4 der 7 punkte... 🙄
    aber da dir es offensichtlich egal ist, brauch ich ja au nix mehr dazu sagen...

    bb



  • 5. ist es doch hässlich, jedes mal wieder this-> vor member zu schreiben - und unnötig

    Ich wätte mal da sist einer der vier übrigen gründe... 😃
    Es ist eine frage des Still's ob man this-> benutzt oder weglässt, ich benutze ihn...

    Der Rest dürfte auch Still sein und jeden selbst überlassen.

    2. wozu eine fkt, wie SetTimeNULL?

    Wozu? Damit man ihn wieder auf Null setzen kann obwohl das wo du schon recht hast unsinnige Methode ist, aber ich hatte einfach mal lust^^ ( 🙄 )

    Mfg Wikinger75!



  • hmm.. hab gerad lange weile und mir is nix entspannteres eingefallen ^^

    #3
    http://de.wikipedia.org/wiki/Initialisierungsliste
    Ist leider ein wenig kurz und das wichtigste fehlt... Hier im Forum gabs das Thema aber mit Sicherheit schon öfters: Die Member werden mit I-Liste nicht erst default konstruiert, sondern es wird sofort der copy-CTor aufgerufen:

    bla::bla(T _member)
    {
     member = _member;
    }
    

    wird also zu so was in etwa:

    • erzeuge bla
    • rufe default-ctor von member auf
    • weise member einen neuen wert zu: _member

    in dem Fall könnte man auch schreiben:

    bla::bla(T _member)
    : member(T())
    {
     member = _member;
    }
    

    also baut man es so:

    bla::bla(T _member)
    : member (_member)
    {}
    

    Es ist zwar am Anfang sehr ungewohnt aber mit der Zeit gewöhnt man sich nicht nur daran, es wird sogar sehr viel übersichtlicher...

    Ich denke auch nicht, dass der Compiler das wegoptimieren darf... Und bei const Werten bzw Referenzen hat man eh keine andere Wahl...

    #7
    http://opengroup.org/onlinepubs/007908799/xsh/usleep.html
    http://opengroup.org/onlinepubs/007908799/xsh/sleep.html

    Außerdem ist die Klasse immernoch unnötig...

    void MySleep(unsigned int milliseconds)
    {
        #ifdef __Windows
          #include <windows.h>
          Sleep(milliseconds);
        #elif defined(_POSIX_VERSION)
          #include <unistd.h>
          if (milliseconds>= 1000) //nicht unbedingt nötig, aber würde imho lasterror überschreiben
              sleep(milliseconds/1000);
          if ((milliseconds%1000) / 1000) //noch mal
             usleep((milliseconds%1000)/1000);
        #else
          #error Not a supported platform
        #endif
    }
    

    allerdings würde ich die fkt wohl Sleep nennen und die Fkt in nen namespace packen...

    Wenns nicht gerade ne Sleep-Fkt wäre, würd ich ja fast sagen, dass es bestimmt nen tolles Beispiel für inline-asm ist ^^

    Da bei nem Sleep die Zahlen eigentlich auch immer zur Compile-Zeit feststehen, könnte man mit templates sicherlich auch was schöneres für unix und ganze sekunden bzw. werte für unter 1s bauen...

    bb


Anmelden zum Antworten