Struktur als Parameter an Thread übergeben
-
Hallo nochmal,
ich hätte da eine Frage über das Übergeben von Parametern an Threads.
Ich habe bisher nur versucht einzelne Parameter an ein Thread zu übbergeben, wobei man es erst nach LPVOID casten musste und im Thread wieder in den gewünschten Typ.Jetzt brauche ich aber 2 Parameter und habe mir dafür eine Struktur angelegt und beide Variablen der Struktur ausgefüllt.
Wenn ich es nun nach LPVOID caste und im Thread zurück gibt es noch keine Fehler, jedoch wenn ich auf eins der beiden Variablen zugreife krieg ein Fehler .
Jetzt hab ich schon vieles vversucht ,bin aber noch nicht auf eine Lösung gekommen, vielleicht kann mir da einer helfen.
Hier ist der Codeabschnitt:
DWORD WINAPI G6_Engine::MeshLoader(LPVOID param) { MeshLoaderParam* temp = reinterpret_cast<MeshLoaderParam*>(param); std::string temp_name(temp->path); MessageBoxA(0,temp_name.c_str(),0,0); return 0; } bool G6_Engine::GFileManager::Load(GMesh* mesh, std::string path) { HANDLE Temp_h = NULL; //Temp Handle für Thread DWORD Temp_d = NULL; //Temp Dword für Thread MeshLoaderParam Temp_param; Temp_param.mesh = mesh; Temp_param.path = path; Temp_h = CreateThread(NULL, 0 ,(LPTHREAD_START_ROUTINE) MeshLoader,reinterpret_cast<LPVOID>(&Temp_param), NULL, NULL); GetExitCodeThread(Temp_h, &Temp_d); //In dem Dword wird der Zustand gespeichert _ThreadMap.insert( std::make_pair<HANDLE , DWORD>(Temp_h,Temp_d)); //Setze den Thread in die map ein return false; }
-
Hmm also so bekomme ich schonmal keine Fehlermeldung, jedoch hat die Ausgabe keinen Inhalt:
MeshLoaderParam &c = reinterpret_cast<MeshLoaderParam&>(param); std::string temp_name(c.path); MessageBoxA(0,temp_name.c_str(),0,0);
-
Ein cast von void * nach referenz wird nicht funktionieren.
versuchs soMeshLoaderParam *c = reinterpret_cast<MeshLoaderParam*>(param); std::string temp_name(c->path); MessageBoxA(0,temp_name.c_str(),0,0);Kurt
-
Du übergibst einen Zeiger auf ein lokales Element.
WennG6_Engine::GFileManager::Load()endet bevorG6_Engine::MeshLoader()damit fertig ist wirdparamungültig...
-
Ja der Befehl G6_Engine::GFileManager::Load() soll ja nur einen Thread starten und seinen HANDLE bzw. den DWORD zur Überprüfung des States in eine map speichern.Und die Threadfunktion selbst parst und lädt dann ein Mesh, sodass Load() natürlich vor dem Thread fertig ist.
Was würdet ihr vorschlagen ?? Ich kann alle eingehenden parameter zum laden eines Meshs nicht in der classe speichern (könnte ich schon wäre aber sehr schlecht)... ??
-
Bob Wolfskin schrieb:
Was würdet ihr vorschlagen ??
Mit
new(evtl. Smartpointer) auf dem Heap anlegen.
-
Und wie genau stellst du dir das vor (mit dem Heap mein ich) ??
-
Meinst du irgendwie sowas:
MeshLoaderParam *m = new MeshLoaderParam; m->mesh = mesh; .....
-
Yeahh ich habs hinbekommen.Für alle mit dem gleichen Problem:
DWORD WINAPI G6_Engine::MeshLoader(LPVOID param) { MeshLoaderParam *c = reinterpret_cast<MeshLoaderParam*>(param); std::string temp_name(c->path); MessageBoxA(0,temp_name.c_str(),0,0); return 0; } bool G6_Engine::GFileManager::Load(GMesh* mesh, std::string path) { HANDLE Temp_h = NULL; //Temp Handle für Thread DWORD Temp_d = NULL; //Temp Dword für Thread MeshLoaderParam* a = (MeshLoaderParam*) malloc(sizeof(a)); new (a) MeshLoaderParam(); a->mesh = mesh; a->path = path; Temp_h = CreateThread(NULL, 0 ,(LPTHREAD_START_ROUTINE) MeshLoader,reinterpret_cast<LPVOID>(a), NULL, NULL); GetExitCodeThread(Temp_h, &Temp_d); //In dem Dword wird der Zustand gespeichert _ThreadMap.insert( std::make_pair<HANDLE , DWORD>(Temp_h,Temp_d)); //Setze den Thread in die map ein return false; }Man erstellt erstmal einen Speicherbereich für die Struktur und dann erstellt man mit new eine Instanz davon.Jetzt kann man das ganze ausfüllen und mit reinterpret_cast casten.In dem Thread einfach zurück und man hats
-
Bob Wolfskin schrieb:
Meinst du irgendwie sowas:
MeshLoaderParam *m = new MeshLoaderParam; m->mesh = mesh; .....Zum Beispiel. (
deletenicht vergessen!)
-
Fehlt nur noch eines
DWORD WINAPI G6_Engine::MeshLoader(LPVOID param) { MeshLoaderParam *c = reinterpret_cast<MeshLoaderParam*>(param); std::string temp_name(c->path); MessageBoxA(0,temp_name.c_str(),0,0); [b]delete c;[/b] // kann in der aufrufenden funktion nicht freigegeben werden return 0; }Kurt
-
Bob Wolfskin schrieb:
MeshLoaderParam* a = (MeshLoaderParam*) malloc(sizeof(a)); new (a) MeshLoaderParam();malloc(sizeof(a))und placement new
Du reservierst lediglich Platz für einen Zeiger.
Mach's so, wie Du selbst eben vorschlugst.
MeshLoaderParam* a = new MeshLoaderParam;
-
malloc(sizeof(a)) und placement new
Du reservierst lediglich Platz für einen Zeiger.
Ja so ist das und es funktioniert einwandfrei

Der Fehler war ja, dass kein Speicherplatz freigegeben wurde und deshalb ein Fehler beim Aufruf die Folge war
-
Bob Wolfskin schrieb:
Ja so ist das und es funktioniert einwandfrei

Das denkst Du nur.
MeshLoaderParamist größer als ein Zeiger. Du zerschießt dir den Heap. Das kann dir jederzeit um die Ohren fliegen.
Warum placement new wenn Du doch nur einnewwillst?
-
Okey ich habs jetzt umgeschrieben, vielen Dank.
Übrigens wenn ich in der Threadfunktion meine instanz mit delete am Ende lösche bricht das Program zusammen.
Wie kann das sein?
-
Okey machts doch nicht, war nur beim placement new so

Vielen Dank für die Antworen
-
Bob Wolfskin schrieb:
Okey machts doch nicht, war nur beim placement new so

malloc() <-> delete => bumm!