Class-Member casten
-
Hi!
Ich will innerhalb einer Klasse einen Thread starten. Die Thread-Funktion ist in der selben Klasse und nicht-statisch. Wenn ich
CreateThread(0, 0, this->Thread, 0, 0, 0);
aufrufe->Fehler.
Casting mit
static_cast<DWORD (*)(void*)>(Thread)
auch erfolglos, genauso wie mit allen anderen Cast-Operatoren.
Kann man da überhaupt casten??
PS: Selbes Problem mit WindowProcedure als Class-Member.
Thx.
-
Hi,
Also ein da einfach so 'rumzucasten' würd ich dir erstmal nicht empfehlen...
Was für Fehlermeldungen bekommst du denn genau ? (Zeig mal die Error-Log.)
Außerdem haben Thread-Proc's eine bestimmte (vorgeschriebene) Syntax; hast du die eingehalten ?
EDIT: BTW: Vllt ist das noch hilfreich: http://www.c-plusplus.net/forum/viewtopic-var-t-is-39356.html
-
Error:
In constructor `CServer::CServer(int)': argument of type `DWORD (CServer::)(void*)' does not match `DWORD (*)(void*)'
Thread-Proc:
DWORD WINAPI CServer::Thread(LPVOID data) { ... return 0; }
Liegt eindeutig am Casting.
-
Da eine ThreadProc eine Signatur wie
unsigned long __stdcall ThreadProc( void *data );
haben muss, muss die Methode statisch sein. Eine nicht-statische Methode würde nicht die Aufrufkonvention __stdcall sondern thiscall haben. Außer es ist eine Methode mit variabler Parameterzahl - was aber für eine ThreadProc auch wieder unbrauchbar ist.
Greetz, Swordfish
-
Swordfish schrieb:
Da eine ThreadProc eine Signatur wie
unsigned long __stdcall ThreadProc( void *data );
haben muss, muss die Methode statisch sein. Eine nicht-statische Methode würde nicht die Aufrufkonvention __stdcall sondern thiscall haben. Außer es ist eine Methode mit variabler Parameterzahl - was aber für eine ThreadProc auch wieder unbrauchbar ist.
Greetz, Swordfish
Wo er Recht hat, hatter Recht
BTW: Du magst immer noch keine Markos/Präprozessordirektiven oder ?^^
-
CodeFinder schrieb:
BTW: Du magst immer noch keine Markos/Präprozessordirektiven oder ?^^
Nö, und solange ich noch keinen 64-Bitter bei mir rumstehen hab', wird sich daran auch aller wahrscheinlichkeit nichts ändern. Und selbst dann denke ich, dass ich mir meine eigenen typedefs (niemals Makros) schreiben werde
Greetz, Swordfish
-
Dr. C++ schrieb:
Kann man da überhaupt casten??
Nein, kann man nicht. Du kannst keine Memberfunktion in eine Non-Memberfunktion casten, auch nicht umgekehrt.
Du kannst dir aber mit einem Trick behelfen, der ganz einfach darin besteht, dass du dem Parameter der Threadfunktion einfach this mitgibst und somit den Aufruf der eigentlichen Thread Memberfunktion durchführen kannst. Dazu erstellst du eine statische Member- oder Non-Memberfunktion, die der ThreadProc Signatur entspricht:
DWORD WINAPI ThreadProc(void* data) { foo& instance = *static_cast<foo*>(data); // foo ist die Klasse deines Objektes, welche das auch immer sein mag instance.Thread(); // Aufruf deiner eigentlichen ThreadProc }
Der Aufruf von CreateThread muss dann auch entsprechend aussehen:
CreateThread(NULL, 0, &ThreadProc, this, 0, NULL);
-
Gleich 2 Fehler gefunden
Der Aufruf von CreateThread muss dann auch entsprechend aussehen: CreateThread(NULL, 0, &ThreadProc, this, 0, NULL);
->
CreateThread(NULL, 0, ThreadProc, (LPVOID)this, 0, NULL);
-
Meckert dir das dein Compiler an? Dann hat er jedenfalls 'ne Macke.
foo und &foo ist im Kontext von Non-Member Funktionszeigern äquivalent. Und da du bei Member Funktionszeigern den Adressoperator brauchst, habe ich mir angewöhnt, ihn grundsätzlich zu verwenden. Und ein Objektzeiger kann immer implizit nach void* umgewandelt werden. Also, _kein_ Fehler!