pthread ohne static



  • Hallo,

    ich will in einer c++ classe ein tread starten.

    leider geht das nur wenn ich die Tread methode "showDisplay" als static deklariere! kann mir jemand sagen warum???

    so funktioniert der code sobald ich static weglasse nicht mehr dann kommt die Fehlermeldung des Compilers

    .cc:20: error: argument of type void*(Showimag::)(void*)' does not matchvoid*()(void)'
    gmake[1]: *** [DescriptorTest.o] Error 1

    ich möchte den Tread ohne das static starten bin aber dankbar für alle hinweise

    Oli

    #ifndef _showimag
    #define _showimag
    #include <pthread.h>
    #include <iostream>
    
    class Showimag
    {
      public:
    
       Showimag(){}
       ~Showimag(){}
    
       static void *showDisplay(void *arg) { std::cout<<"juhu"<<std::endl; return 0; }  //warum muss ich hier static declarieren???
    
       void startDisplay() { pthread_create(&ShowThreadID, NULL, showDisplay, NULL); }
    
       private:
    
       pthread_t ShowThreadID;     //thread
    
    };
    #endif
    
    int main()
    {
       Showimag a;
      a.startDisplay();
      return 0;
    }
    


  • Morgen,

    es funktioniert nicht, weil du keinen Zeiger auf eine Funktion, sondern einen
    Zeiger auf eine Elementfunktion uebergibst und diese implizit noch den this-Zeiger
    mitfuehrt. Daher passt der Parameter nicht zu dem erwarteten Parameter.

    mfg
    v R



  • Ok mit dem Zeiger auf eine Elementfunktion meinst du sicher denn NULL Pointer und zwar den letzen in der folgenden Code Zeile:

    void startDisplay() { pthread_create(&ShowThreadID, NULL, showDisplay, NULL); }
    

    wenn ich aber hier in der Tread Methodee:

    static void *showDisplay(void *arg) { std::cout<<"juhu"<<std::endl; return 0; }
    

    den den übergeben parameter NULL nenn geht das auch net. da Pthread hier ein pointer erwartet...
    Ich will doch gar nichts übergeben. Wie änder ich nun am besten die aufrufende Funktion startDisplay damit ich showDisplay das übergeb was es erwartet?

    mgf Oli



  • Das hat mit dem letzten Parameter nichts zu tun. Ist showDisplay static, fuehrt
    die Funktion den this-Zeiger nicht implizit mit, weswegen du auch nicht auf
    Member der Klasse zurueckgreifen kannst.

    Ist showDisplay aber nicht static, wird der this-Zeiger implizit mitgefuehrt.
    Du uebergibst dann einen Zeiger auf eine Elementfunktion, was nicht mit dem
    erwarteten Parameter kompatibel ist.

    Deine einzige Moeglichkeit bleibt es, showDisplay als static zu deklarieren,
    so wie ich das sehe.

    mfg
    v R



  • Genau das ist das Problem ich möchte in der Funktion showDisplay auf Member der Klasser zurückgreifen können und sie deshalb auch nicht als static declarieren.

    Mensch da muss es doch ein lösung geben!!
    aber ich dank dir mal auf jeden fall für deine Hinweise und Mühe



  • Warum uebergibst du nicht 'this' als letztes Argument? Und machst dann in der
    uebergebenen Funktion einfach einen Cast auf Showimag*?!

    mfg
    v R



  • Das ist schlicht und ergreifend nicht möglich. Wie schon gesagt funktioniert der Aufruf von non-static Methoden mittels eines zusätzlichen Parameters der letztlich den this-Zeiger darstellt. pthread_create() erwartet aber keine Methode, sondern eine Funktion, also etwas ohne Instanz, darum funktioniert es mit static, weil dadurch aus einer Methode "quasi" eine Funktion wird.

    Du kannst das Problem nur zweistufig lösen:

    void *showDisplay() {  std::cout<<"juhu"<<std::endl; return 0; }
       static void *showDisplayStarter(void *arg) { return static_cast<Showimag*>(arg)->showDisplay(); }
    
       void startDisplay() { pthread_create(&ShowThreadID, NULL, showDisplayStarter, this); }
    


  • Davon hab ich auch gesprochen 😉

    mfg
    v R



  • Klar, sorry Realisticer, das bezog sich natürlich nicht auf Deine Antwort, die war noch nicht da als ich auf Antworten geklickt habe. 🤡



  • Hutzli schrieb:

    Klar, sorry Realisticer, das bezog sich natürlich nicht auf Deine Antwort, die war noch nicht da als ich auf Antworten geklickt habe. 🤡

    Aso 🙂

    mfg
    v R



  • Ok Ich übergeb this als letztes argument das sieht dann so aus:

    pthread_create(&ShowThreadID, NULL, showDisplay,this);
    

    und wie cast ich nun in der übegeben Funktion auf Showimag????

    hab das so probiert:

    static void *showDisplay(void *arg) 
       {
    	  std::cout<<"blaaaa"<<Showimag::aha<<std::endl; return 0; 
       }
    
       void startDisplay() 
       {
    	aha=6;
        pthread_create(&ShowThreadID, NULL, showDisplay,this);
       }
    
       private:
    
       pthread_t ShowThreadID;     //thread
    
       int aha;
    

    aber da kommt folgende Fehlermeldung vom Compiler :

    .cc: In static member function static void* Showimag::showDisplay(void*)': .cc:29: error: memberShowimag::aha' is non-static but
    referenced as a static member
    .cc:16: error: at this point in file
    .cc:16: confused by earlier errors, bailing out



  • Hast du dir Hutzli's Beispiel ueberhaupt mal angeschaut? 😉

    mfg
    v R



  • hab mein Beitrag geschrieben bevor ich hutzlis beispiel gesehn hab...
    Jetzt tut es ich danke auch beiden ganz doll

    mfg oli 23



  • Jetzt frag ich einfach nur nochmal nach...

    die zeile kann mir die jemand erklähren???

    { return static_cast<Showimag*>(arg)->showDisplay(); }
    

    mfg oli 23



  • void *showDisplay() {  std::cout<<"juhu"<<std::endl; return 0; }
       static void *showDisplayStarter(void *arg) { return static_cast<Showimag*>(arg)->showDisplay(); }
    
       void startDisplay() { pthread_create(&ShowThreadID, NULL, showDisplayStarter, this); }
    

    oli 23,
    du gibst showDisplayStarter als Parameter den Thiszeiger mit.
    Diesen musst du dann wieder von void zurückcasten.

    Der Thiszeiger ist aber sehr wichtig, weil du sonst nicht weißt in welcher Instanz zu gerade bist.


Log in to reply