Aufruf von pthread_create innerhalb einer member-Funktion?
Erstellte ich ein widget.h-Datei mit den declartions von pthread_function
und ich wollte es nennen, in eine member-Funktion destroyWidget
der Klasse Widget in widget.cpp. aber zeigt immer einen Fehler an. Ich zeige das .cpp und .h-Datei.
widget.h-Datei
class Widget
{
public:
Widget();
void createWidget(int x,int y,int w,int h);
void showWidget();
int wid;
pthread_t thread;
int *incomingval,id;
void join();
Window win;
XEvent evt;
private:
void* destroyWidget(void* ptr);
Display *disp;
int screenNumber;
unsigned long white;
unsigned long black;
long eventMask;
GC gc;
int tbit;
int *incoming,val;
};
nun die widget.cpp
Widget::Widget()
{
disp=XOpenDisplay( NULL );
screenNumber=DefaultScreen(disp);
white=WhitePixel(disp,screenNumber);
black=BlackPixel(disp,screenNumber);
eventMask=StructureNotifyMask;
tbit=0;
}
void Widget::createWidget(int x,int y,int w,int h)
{
wid=w;
win= XCreateSimpleWindow(disp,DefaultRootWindow(disp),x,y,w,h,1,white,black);
}
void Widget::showWidget()
{
XMapWindow(disp,win);
XFlush(disp);
gc=XCreateGC(disp,win,0,NULL);
XSetForeground(disp,gc,white);
XDrawLine(disp,win,gc,wid-10,0,wid,10);
XDrawLine(disp,win,gc,wid-10,10,wid,0);
//calling the thread function
pthread_create( &thread, NULL, destroyWidget, this);
}
void Widget::join()
{
pthread_join( thread, NULL);
}
void* Widget::destroyWidget(void* ptr)
{
Widget* mw = static_cast(ptr);
eventMask=ButtonPressMask|ButtonReleaseMask;
XSelectInput(disp,win,eventMask);
do{
printf("id= %d",id);
XNextEvent(disp,&evt);
}while(evt.type!=ButtonRelease);
XDestroyWindow(disp,win);
XCloseDisplay(disp);
return NULL;
}
nun die main.cpp Datei
#include "widget.h"
#include
int main()
{
Widget* w=new Widget();
Widget* n=new Widget();
n->createWidget(20,20,150,150);
w->createWidget(50,50,250,250);
n->showWidget();
w->showWidget();
n->join();
w->join();
return 0;
}
den Fehler
widget.cpp: In member function ‘void Widget::showWidget()’:
widget.cpp:44:51: error: argument of type ‘void* (Widget::)(void*)’ does not match ‘void* (*)(void*)’
- Indendation wirklich nicht viel, um Ihren code lesbar. Ich empfehle sehr, es in die Zukunft. Auch nur ein paar Räume wären chill.
- Sollten Sie NICHT verwenden Sie eine member-Funktion gar Nicht statisch ist. Lesen Sie hier die richtige Lösung. stackoverflow.com/questions/6352280/pthread-create-error-in-c/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem ist, dass
pthread_create
ist ein C-style-Funktion; Sie müssen, um ihm einen Zeiger auf Funktion.Widget::destroyWidget()
ist ein Zeiger-auf-Mitglied-Funktion. (Denken Sie daran, dass nicht-statische member-Funktionen haben immer eine implizitethis
argument, diepthread_create
weiß nicht, wie zu bieten.)Finden Sie die Antworten auf diese Frage einige mögliche Lösungen: pthread-Funktion aus einer Klasse.
static
helper-Funktion, die wiederum ruft die Mitglied-Funktion?extern "C"
, und jede Sprache, Verknüpfung auf die member-Funktionen wird ignoriert.Das Dritte argument
pthread_create
hat die Signatur (in C++):Sie versuchen, übergeben Sie ihm die Adresse einer member-Funktion:
Die Signaturen inkompatibel sind: der zweite benötigt ein Objekt, auf dem
es zu nennen, und ist nicht
extern "C"
.Die einfachste Art des Umgangs mit diesen ist die Verwendung
boost::thread
mit allenes ist funktional-Objekt-Unterstützung. Andernfalls können Sie definieren etwas
wie die folgenden:
Starten einen thread, dann rufen Sie:
(Dies ist aus der Erinnerung aus einem früheren Projekt, so könnte es einige
Tippfehler drin, aber Sie bekommen die Idee. Und Sie wahrscheinlich wollen, fügen Sie einige
Fehlerbehandlung in
taskStarter
.)pthread_create
ist ein Zeiger auf eine Funktion, die wirft das argument ein Zeiger auf eine Schnittstelle, und ruft eine Funktion in es. Dann leiten Sie von der Schnittstelle zu tun, was Sie wollen; in diesem Fall, um die Dinge einfacher, es gibt eine Vorlage zum erstellen der abgeleiteten Klasse, so dass Sie nicht haben, es zu schreiben, jedes mal. Und die eigentliche Funktion übergebenpthread_create
wird zerstören das Objekt, das Sie erstellt haben; seit Polymorphismus beteiligt ist, und das Leben folgt nicht den Geltungsbereich, die Sienew
es.Wie Oli schon sagte, Sie können nicht, verwenden Sie eine member-Funktion, wenn Sie eine C-Funktion erwartet einen "normalen" Funktions-pointer. Jedoch, was Sie tun können, ist eine separate Funktion, dass die Anrufe wieder Ihre destroyWidget () - Methode.
Etwa so:
pthread_create(&thread, NULL, start_routine, this);
(kein kaufmännisches und-Zeichen nehmen Sie einen Funktionszeiger).