Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

CString in ThreadFunktion

Empfohlene Antworten

Veröffentlicht

Servus Gemeinde,

ich suche nach einer Möglichkeit einen CString als Parameter in eine

ThreadFunktion zu übergeben. Bei CreateThread steht mir ja LPVOID als

Paremeter zu Verfügung. Wie bekomme ich den dazu einen CString zu akzeptieren?

TinTin


DWORD WINAPI  threadCreateZip(CString test)

{


		AfxMessageBox(test);

		return 0;

}


	CreateThread(NULL,

                                0,

                                threadCreateZip,

                                test,

                                NULL,

                                &ThreadId);

So gehts natürlich nicht, aber so sollte es im Prinzip aussehen.

Du kannst jeden beliebigen Zeiger in den Thread reingeben, und dann im Thread durch einen passenden Cast wieder rausholen. Du musst nur darauf achten, dass die Lebensdauer des Objekts, dessen Adresse du übergibst, lang genug ist. Die Adresse eine Autovariablen zu benutzen, ist also meist eine ziemlich schlechte Idee.

Danke, so schauts aus.

typedef struct threadArgs

{

  LPCTSTR lpDBPath;

  LPCTSTR lpZipName;

} threadArgs; 


DWORD WINAPI threadCreateZip(LPVOID lParam)

{


	threadArgs *ta;

	ta = (threadArgs*) lParam; 

	TRACE("arg1:%s arg2:%s",ta->lpZipName,ta->lpDBPath);

	return 0;

}

...

HANDLE hThread = CreateThread(NULL,

				0,

				threadCreateZip,

				(LPVOID)&ta,

				NULL,

				&ThreadId);


	if (hThread != INVALID_HANDLE_VALUE)

	{

		WaitForSingleObject(hThread, INFINITE);

		DWORD dwExitCode;

		GetExitCodeThread(hThread, &dwExitCode);

		CloseHandle(hThread);

		return;

	}

Drei Anmerkungen:

Wie ist ta deklariert? Ist das eine lokale Variable? Falls ja, könnte das zu den oben erwähnten Problemen führen, falls du mal nicht auf das Ende des Threads wartest.

Zweitens: Wenn du Zeiger in deiner threadArgs-Struktur benutzt, gilt für die Lebensdauer der Objekte, auf die diese Zeiger verweisen, das gleiche wie für die Struktur selbst.

Und drittens ist ein Thread ziemlich sinnlos, wenn du gleich nach dem Starten auf das Ende wartest. Oder war das nur ein Beispiel?

Wie ist ta deklariert? Ist das eine lokale Variable? Falls ja, könnte das zu den oben erwähnten Problemen führen, falls du mal nicht auf das Ende des Threads wartest.

ta ist lokal in einer Dialogklasse deklariert, beinhaltet aber 'nur' zwei Pfade, die direkt inder

TreadFunktion genutzt werden. kann ich aber auch global deklarieren.

Zweitens: Wenn du Zeiger in deiner threadArgs-Struktur benutzt, gilt für die Lebensdauer der Objekte, auf die diese Zeiger verweisen, das gleiche wie für die Struktur selbst.

Was ist denn sinnvoller, denn meinem Code sind die ta-Member Zeiger auf

zwei Klassen-Menbervariablen


	threadArgs ta;

	ta.lpDBPath = m_csDBFullPath;

	ta.lpZipName = m_csFullBackUpPath;
Und drittens ist ein Thread ziemlich sinnlos, wenn du gleich nach dem Starten auf das Ende wartest. Oder war das nur ein Beispiel?
Ist nur ein Beispiel und
WaitForSingleObject(hThread, INFINITE);

hat da auch Nichts mehr zu suchen

TinTin

Mal zwei Beispiele:


int foo()
{
threadArgs ta;
CreateThread(&bar, &ta); // Stark vereinfacht
// <- hier wird ta zerstört
}

int bar(void* param)
{
threadArgs* ta = (threadArgs*)param; // <- gibt es das Objekt überhaupt noch?
}[/code] Du kannst hier nicht sicher sein, dass die lokale Variable ta in foo überhaupt noch existiert, wenn du im Thread bar die Adresse rausholst. Das ist genauso böse wie das Zurückgeben der Adresse einer lokalen Variablen. 2. Beispiel
[code]class someclass
{
threadArgs m_ta;
int foo()
{
CreateThread(&bar, &m_ta); // Stark vereinfacht
m_ta.m_intMember++;
}
};

int bar(void* param)
{
threadArgs* ta = (threadArgs*)param;
int wichtig = ta->m_intMember; // <- Welcher Wert landet hier?
}

Hier ist die Lebensdauer kein Problem. Aber du kannst nicht wissen, ob zuerst im someclass::foo der int-Member erhöht, oder im Thread bar ausgelesen wird. Dieses Problem tritt immer dann auf, wenn du die Threadparameter ändern könntest - wie in deinem Fall.

Und es ist natürlich Quatsch, Adressen von globale Variablen als Threadparameter zu übergeben. An globale Variablen kommst du ja auch so ran.

Wenn du nicht ganz sicher bist, dass das Parameterobjekt lange genug lebt und unveränderlich ist - zumindest bis der Thread eine Kopie anlegen konnte - solltest du entweder Synchronisierungsobjekte benutzen oder die Parameter für jeden einzelnen Thread auf dem Heap anlegen.

Und es ist natürlich Quatsch, Adressen von globale Variablen als Threadparameter zu übergeben. An globale Variablen kommst du ja auch so ran.

Wie Recht du hast ich war wohl geistig etwas verwirrt.

Das mit den Syncronisierungsobjekten sieht ganz interessant aus, ist mir für den

Moment aber zu aufwendig. Ich lege die Parameter auf den Heap, dass sollte

für den Moment reichen.

Danke für Deine Hilfe,

TinTin

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.