C++ Visual Studio Threads

Fireball89

Captain
Registriert
Aug. 2007
Beiträge
3.498
Hallo,

ich versuche mich grad mal daran Threads in Visual Studio C++ 2010 Express zu benutzen.
Gefunden habe ich dazu dieses Tutorial:
http://www.codeproject.com/KB/threads/MultithreadingTutorial.aspx

Das Problem dabei: Ich will dem Thread einen Pointer auf ein Objekt übergeben. Jedoch muss ich diesen vorher auf void* typecasten. Das geht zwar, aber wenn ich das gemacht habe, kann das Objekt nicht ansprechen. Ich kann es auch nicht wieder "zurück typecasten". Wie bekomme ich nun mein Objekt in den Thread?

main.cpp
Code:
_beginthread(ThreadRoutine, 0, (void*)meinObjekt);

ThreadRoutine
Code:
if(meinObjekt->IsEmpty())
Verursacht Fehler, da meinObjekt nicht den richtigen Objekttyp hat, sondern void*

Wie löse ich das Problem?
 
Was ist "meinObjekt" - ein Zeiger oder ein normales Objekt? Für Zeiger muss (void *)meinObjekt hinkommen, für normale Objekte (void *)&meinObjekt. In der Funktion selbst, musst du auf gleichem Wege wieder zurückcasten - (meinTyp *)Objekt oder *((meinTyp *)meinObjekt), ggf. auch C++ Casts nutzen.
 
Oder der C++ Weg - casten von und zu void-Pointern sollte auch mit dem static_cast funktionieren:
Code:
static_cast<void*>(&meinObjekt);
static_cast<Class*>(meinObjekt);
 
Achja, bin ich blöd^^
MeinObjekt ist ein Pointer auf ein Objekt. (Objekttyp*)MeinObjekt geht (hab vorher das Sternchen vergessen).

Danke für die Hilfe!
 
Simpson474 schrieb:
Oder der C++ Weg - casten von und zu void-Pointern sollte auch mit dem static_cast funktionieren:
Code:
static_cast<void*>(&meinObjekt);
static_cast<Class*>(meinObjekt);

Das Casten ZU einem void-Pointer kannst du dir übrigens komplett sparen. Die Umwandlung ist implizit. Nur in umgekehrter Richtung wird ein Cast benötigt. :)
Ergänzung ()

Fireball89 schrieb:
Achja, bin ich blöd^^
MeinObjekt ist ein Pointer auf ein Objekt. (Objekttyp*)MeinObjekt geht (hab vorher das Sternchen vergessen).

Danke für die Hilfe!

Trotzdem solltest du dir gleich angewöhnen, mit den C++-Castoperatoren zu arbeiten. Vergiß die alten C-style-Casts. static_cast < Objekttyp* > ( blabla ) ist definitv besser als (Objekttyp*) blabla.
 
Zuletzt bearbeitet:
@antred:
Danke für die beiden Hinweise!
Zu den C++ Casts: um den return von _beginthreadex zu einem HANDLE zu casten, darf ich anscheinend nur die alten Casts verwenden. Sonst bekomme ich: "Ungültige Typkonvertierung". Woran liegt das?
 
Dafür brauchst du den Vorschlaghammer unter den Cast-operatoren, den reinterpret_cast. :)

uintptr_t blubber = _beginthreadex( .... );
HANDLE myHandle = reinterpret_cast < HANDLE > ( blubber );

_beginthreadex() gibt einen uintptr_t zurück, was in der Regel lediglich ein typedef für unsigned int ist. HANDLE hingegen ist ein typedef für void*. Integer nach Pointer casten kann nur der reinterpret_cast.
 
static_cast lässt dich nur "sinnvolle" casts machen. Also Dinge, die vielleicht wirklich zusammenhängen.

Wohingegen kannst du mit dem C-Casts ((Object*)) immer casten, auch wenns echt kein Sinn macht.
Beispielsweise: *(int*)0=0 ist eine schöne Access-Violation, mitm static_cast nicht so einfach zu machen.
Die C-casts sind wie eine Mixtur aus static_cast (wenn eine definierte Umwandung existiert) und wie der reinterpret_cast (wenn keine Umwandung exisitert). daher manchmal (oft) nicht direkt vorhersagbar im Verhalten.

Aber vielleicht erzähl ich nur wirres Zeug, ich verwende immer den cast, der funktioniert und kurz ist (also den C-Cast :D)
 
antred schrieb:
Das Casten ZU einem void-Pointer kannst du dir übrigens komplett sparen. Die Umwandlung ist implizit.
Ein impliziter Cast ist in der Automotive-Welt nicht gerne gesehen, von daher habe ich mir das abgewöhnt ;)
 
Hmmm, ok. Aber verstehen tue ich das ned. Was sagt denn die Automotive-Welt dazu, daß überhaupt irgend was zu void* gecastet wird und damit sämtliche Typsicherheit zum Fenster raus fliegt? ;)
 
Wirklich gern gesehen ist der Cast nach void* natürlich nicht, aber an ein paar Stellen hat man eigentlich keine andere Möglichkeit.
 
Zurück
Oben