PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Thread einer Klassenmethode? (c++)



scar
24-03-2006, 10:04
Sers,
ich möchte nen Thread innerhalb einer Klasse starten.
Beispiel:


class bla
{
public:
void *threadFunc(void* nothing);
void init()
{
pthread_create(&thread,NULL,threadFunc,NULL);
}
protected:
pthread_t thread;
}

Das funktioniert aber nicht, da threadFunc eine Methode der Klasse ist.
Habe auch schon die SDL_Threads ausprobiert(da es nen sdl Programm ist) und den selben Fehler bekommen.
Ich weiß das man sowas mit den threads der Glib machen kann.
Allerdings halte ich es für Übertrieben in ein Plattformunabhängiges Programm die gesamten GTK/Glib Libs mit zu verlinken.
Ich hoffe ihr könnt mir da irgendwie weiterhelfen.
Danke, Christian

Joghurt
24-03-2006, 13:22
So könnte es evtl. klappen (ungetestet)


class bla
{

public:
void* threadFunc();
private:
inline static void* threadFuncWrapper(void* this_)
{
return ((bla*)this_)->threadFunc();
}
public:
void init()
{

pthread_create(&thread,NULL,&threadFuncWrapper,this);
}

protected:
pthread_t thread;
};

Grund:
bla a;
a.foobar() ist mehr oder weniger:
bla a;
bla::foobar(&a)der erste Parameter einer Klassenfunktion ist immer class* und heißt this. Bei static Funktionen fehlt dieser Parameter.

Ich hatte zuerst versucht, dass ganze ohne Wrapper zu machen

void* threadFunc();
...
pthread_create(&thread,NULL,&bla::threadFunc,this)aber C++ weigert sich aus Sicherheitsgründen, die (in diesem Falle korrekte) Umwandlung nach void*(*)(void*) vorzunehmen, selbst wenn ich das explizit angebe.

locus vivendi
24-03-2006, 13:39
Das ist eine FAQ:
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2

scar
24-03-2006, 21:31
So könnte es evtl. klappen (ungetestet)


inline static void* threadFuncWrapper(void* this_)
{
return ((bla*)this_)->threadFunc();
}


Hm, das klappt net, wegen return und void*:
error: void value not ignored as it ought to be
Aber ich brauch doch nen void* für den Thread.. :(

locus vivendi
25-03-2006, 11:50
Hm, das klappt net, wegen return und void*:
error: void value not ignored as it ought to be
Aber ich brauch doch nen void* für den Thread..
Es ist auch nicht Sinn der Sache, jedes Code-Beispiel ungeprüft 1-zu-1 zu übernehmen, meiner Meinung nach jedenfalls. Und wenn du selber den Fehler bzw. die Änderungen die du ggf. vornehmen müsstest nicht siehst, dann wirst du schon deinen Code posten müssen, sonst kann man dir schlecht oder gar nicht helfen.

anda_skoa
28-03-2006, 14:37
Das Beispiel ist ansich fast richtig, nur müssen beide Methoden void sein, nicht void*

Und da dann beide nichts liefern fällt im Wrapper das return weg.

Ciao,
_

Joghurt
28-03-2006, 15:02
Das Beispiel ist ansich fast richtig, nur müssen beide Methoden void sein, nicht void*Wieso?


int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);Eindeutig void* und nicht void, oder nicht?

anda_skoa
28-03-2006, 15:15
pthread_create(&thread,NULL,&threadFuncWrapper,this);

:D

Ciao,
_

Joghurt
28-03-2006, 17:23
Ist doch Jacke wie Hose ob man nun "foo" oder "&foo" schreibt, um die Adresse der Funktion zu bekommen.

anda_skoa
31-03-2006, 17:23
void* ist aber ein anderer Rückgabewert als void

Beim ersten erwartet der Compiler ein return von einem Pointer, beim zweiten kannst du einfach return machen.

Ciao,
_

scar
05-04-2006, 12:27
Habs jetzt auf jeden Fall hinbekommen.
Hab ne Funktionsdeklaration mit extern "C" gemacht.
Dann schön die Funktionen geschrieben


void* bla(void* _class)
{
(MyClass*)(_class)->function();
return 0;
}

Der Aufruf kommt dann über pthread_create und schwuppens, es funzt.
Hab allerdings sdl-threads genommen.
Was jetzt wieder geändert wird.
Wers übrigens gan einfach haben will:
http://cvs.linuxsampler.org/cgi-bin/viewcvs.cgi/linuxsampler/src/common/Thread.cpp?rev=HEAD&content-type=text/vnd.viewcvs-markup
Hoffe das hilft zukünftigen Suchern.

Joghurt
05-04-2006, 14:20
Ich verstehe bis heute das Problem nicht. Bei mir kompiliert und läuft mein Code einwandfrei.

Welchen Compiler/Version hast du denn benutzt?

scar
05-04-2006, 17:24
Benutze derzeitig gcc 3.3.6.
Weiß noch net ob ich auf 4.5 update, läuft so gut :P(gentoo)