Kriege Thread nicht erstellt
-
Hallo!
Ich habe folgende Klasse:#include "streammanager.h" cStreamManager::cStreamManager() { mPlaylist = new cPlaylist; mStream = new cStream(mPlaylist); pthread_create(&mStreamThread, 0, &cStreamManager::Play, 0); mStream->OpenStream(); //mStream->Play(); mStream->CloseStream(); } cStreamManager::~cStreamManager() { delete mStream; delete mPlaylist; } void *cStreamManager::Play(void* arg) { mStream->Play(); return 0; }
Das auskommentierte mStream->Play(); war der ursprüngliche Funktionsaufruf
ohne separaten Thread.
Die dazugehörige Headerdatei:#ifndef STREAMMANAGER_H #define STREAMMANAGER_H #include <pthread.h> #include "stream.h" #include "playlist.h" class cStreamManager { public: cStreamManager(); ~cStreamManager(); private: cStream *mStream; cPlaylist *mPlaylist; pthread_t mStreamThread; void *Play(void* arg); }; #endif
Hier beschwert sich der Kompiler mit:
cannot convert 'void* (cStreamManager::*)(void*)' to 'void* (*)(void*)' for argument '3' to 'int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)'
Wenn anstatt &cStreamManager::Play nur &Play angegeben wird, beschwert sich
der Kompiler mit:ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&cStreamManager::Play'
Ich will, dass anstatt dem Funktionsaufruf mStream->Play(); das ganze in einem
eigenen Thread abläuft. Dabei kann es mehrere Objekte von cStream geben, die
alle was anderes abspielen. Das sind meine ersten Versuche mit Threads.
Was mach ich falsch?PS: Ist es richtig, dass die Funktion, die aufgerufen wird, einen Voidzeiger
als Argument haben muss, obwohl ich kein Argument benötige? Und muss diese
Funktion immer einen Voidzeiger zurückliefern?
-
Versuch halt mal
pthread_create(&mStreamThread, 0, (void*)&cStreamManager::Play, 0);
-
Nee, kompiliert auch nicht.
-
Du kannst Classmember nicht so benutzen, da sie ja von einem Objekt abhängen. Daher musst du pthread_create eine Funktion oder statische Methode übergeben, die die entsprechende Methode aufruft. In etwa so:
class foo { pthread_t thread; static void *bar_caller(void *self) { assert(self); static_cast<foo*>(self)->bar(); return 0x0; } public: void bar() { /* ... */ } void init() { pthread_create(&thread, 0x0, &foo::bar_caller, static_cast<void*>(this)); } };
btw. schau dir vielleicht auch Boost.Threads an.
-
Per statische Methode ist es auch falsch. Die Funktion muss extern "C" sein.
-
Ich hab's jetzt mit einer statischen Wrapperfunktin gemacht.
Ich hoffe, das macht bei mehreren unabhängigen Instanzen keine Probleme:void* cStreamManager::PlayWrapper(void* _This) { return ((cStreamManager*)_This)->Play(0); }
-
Und welche Vorteile bringen mit Boost Threads gegenüber Posix?
Das Prinzip scheint ja das gleiche zu sein.
-
Nur so nebenbei: Das sieht sehr nach Java-Code aus. Wie bekommt man Java-Programmierer dazu, unter C++ nicht alles über Zeiger auf den Heap zu legen? Lege ich eine Instanz im Konstruktor an und lösche sie im Destruktor wieder, dann brauche ich sie nicht als Heap-Objekt anzulegen.