4 votes

Comment créer des threads dans les dlls (c++) ?

Je sais que je ne peux pas créer de threads à partir de DllMain, mais quelle est l'approche correcte pour créer des threads dans une DLL ?

J'ai essayé de créer une classe qui l'englobe et de déclarer une instance globale de cette classe, mais WaitForSingleObject se bloque dans le destructeur de la classe, même si je suis certain que le thread est sorti.

Voici mon programme d'exemple pour charger la dll à partir d'un exe :

#include <Windows.h>
#include <iostream>

using namespace std;

int main(int argc, TCHAR* argv[])
{
    HMODULE module = LoadLibraryA("dll.dll");
    Sleep(500);
    if (module) FreeModule(module);
    else cout << "failed to load library...\n";
    return 0;
}

Et voici le code dll :

#include <Windows.h>
#include <iostream>

using namespace std;

class X
{
    HANDLE thread = NULL;

    static DWORD WINAPI run_thread(LPVOID param)
    {
        cout << "dll.cpp: thread started\n";
        Sleep(1000);
        cout << "dll.cpp: thread is exiting\n";
        return 0;
    }

public:
    X()
    {
        DWORD tmp;
        thread = CreateThread(NULL, 0, run_thread, NULL, 0, &tmp);
        if (thread == NULL)
        {
            cout << "failed to create thread\n";
            throw 1;
        }
    }
    ~X()
    {
        if (thread != NULL)
        {
            cout << "joining thread...\n";
            DWORD ret = WaitForSingleObject(thread, INFINITE);
            cout << "result from waiting: " << ret << "\n";
            thread = NULL;
        }
    }
}x;

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
{
    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
        cout << __FUNCTION__ << " reason DLL_PROCESS_ATTACH\n";
        break;
    case DLL_THREAD_ATTACH:
        cout << __FUNCTION__ << " reason DLL_THREAD_ATTACH\n"; 
        break;
    case DLL_THREAD_DETACH:
        cout << __FUNCTION__ << " reason DLL_THREAD_DETACH\n"; 
        break;
    case DLL_PROCESS_DETACH:
        cout << __FUNCTION__ << " reason DLL_PROCESS_DETACH\n"; 
        break;
    }

    return TRUE;
}

Voici la sortie du programme :

DllMain reason DLL_PROCESS_ATTACH
DllMain reason DLL_THREAD_ATTACH
dll.cpp: thread started
DllMain reason DLL_PROCESS_DETACH
joining thread...
dll.cpp: thread is exiting
                            <- notice how WaitForSingleObject hangs,
                               even though the thread has exited

Quel est le problème de cette approche ?

Si j'enlève le Sleep(1000) de Exécuter un fil de discussion de sorte que le fil se termine avant que WaitForSingleObject ne soit appelé, et qu'il ne se bloque pas :

DllMain reason DLL_PROCESS_ATTACH
DllMain reason DLL_THREAD_ATTACH
dll.cpp: thread started
dll.cpp: thread is exiting
DllMain reason DLL_THREAD_DETACH
DllMain reason DLL_PROCESS_DETACH
joining thread...
result from waiting: 0

Je ne comprends pas la différence, et ce n'est pas non plus une option, puisque le but du thread est de boucler constamment tant que DLL_PROCESS_DETACH n'est pas signalé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X