есть длл на DLL_PROCESS_ATTACH создается поток в этом потоке бесконечный цикл DWORD WINAPI BackConnectLoop(LPVOID lpParam) { //инициализация сокетов бла бла for(; { connect(....) sleep(800); } return 0 } и собственно на DLL_PROCESS_ATTACH DWORD dwIDMainConn; HANDLE hThreadMainConn = CreateThread(NULL,0,&BackConnectLoop,NULL,0,&dwIDMainConn); но как правильно сделать на DLL_PROCESS_DETACH делал так DWORD ExitCode(0); GetExitCodeThread(hThreadMainConn,&ExitCode); TerminateThread(hThreadMainConn,0); WaitForSingleObject(hThreadMainConn,INFINITE); пожно как то поток уведомить на выгрузку длл
делал вот так еще bool bCheck; DWORD WINAPI BackConnectLoop(LPVOID lpParam) { //инициализация сокетов бла бла while(bCheck == true) { connect(....) sleep(800); } ExitThread(0); /// доходит сюда и висит return 0 } DLL_PROCESS_ATTACH bCheck = true; DWORD dwIDMainConn; HANDLE hThreadMainConn = CreateThread(NULL,0,&BackConnectLoop,NULL,0,&dwIDMainConn); DLL_PROCESS_DETACH bCheck = false; WaitForSingleObject(hThreadMainConn,INFINITE); в потоке ExitThread(0); висит почему ? не пойму естественно WaitForSingleObject ожидаем до безкочечности
Вы можете просто оставить return 0. ExitThread нужен для не предвиденного выхода из потока, но в конце функции это не обязательно. И что значит висит. может она просто из нее не возвращается, как и в случае с ExitProcess.
работает только когда вмнесто ExitThread(0) сделать вот так DWORD dwExitCode; GetExitCodeThread(GetCurrentThread(),&dwExitCode); TerminateThread(GetCurrentThread(),dwExitCode);
висит имелось ввиду когда пошагово дохожу до ExitThread(0) cpp отладчиком то вызывается ExitThread(0) и все
Завершать потоки при захваченной LdrpLoaderLock весьма плохое решение. Ядро помогает освобождая кс, но это может закончится общей рассинхронизацией, например зависанием иного потока обратившегося к загрузчику.
я делал так... один поток в цикле принимал оконные сообщения: if(IsGUIThread(TRUE) == FALSE) { return 1; } // Важный момент ... while(m_bWorking) // Цикл обработки команд из вне { GetMessage(&msg, NULL, 0, 0); switch(msg.message) { ... case CTRLMES_EXIT: // Команда на завершение работы DLL m_bWorking = false; break; ... } } ... // Освобождение ресурсов потока return 0; // Выход потока другой работал со своими задачами: while(m_bWorking) { .... } // Освобождение ресурсов потока return 0; // Выход потока управляющие сообщения посылались из другого процесса с помощью PostThreadMessage, m_bWorking - глобальная булевая переменная, инициализированная true... ещё важно заботиться об использованных ресурсах... очищать память и закрывать хендлы, так как они ассоциируются с процессом, а не с потоком... забивание на них в итоге может привести к некорректному завершению процесса или например к блокировке доступа к файлу... вообще если о памяти говорить, то лучше использовать кучи, а если говорить о потоках, то лучше использовать _beginthread... ты спросишь "почему?" - читай ответ у Рихтера))))
to Rel Насколько я понял в данном случае При вызове LoadLibrary будет крутится цикл в текущем потоке то есть приложение которое вызывает LoadLibrary на ней остановится и будет ожидать остановки цикла только тогда можно выполнять какой нить код мне нужно что бы не было "остановки" на LoadLibrary
в DllMain не логично делать никаких циклов... в данном случае в DllMain создаются два потока: рабочий и обработки сообщений... чтобы прервать работу dll достаточно послать сообщение о выгрузке потоку обработчику сообщений, подождать завершения потоков и вызвать FreeLibrary... плюс ещё в том, что подобные вещи удобно делать из другого процесса...
to Rel "подождать завершения потоков и вызвать FreeLibrary" а если поток бесконечный то есть цикл while(1) а тут надо выгрузить длл тогда как лучше сделать ?
ты вообще читал, что я выше написал тебе? уже второй дурацкий вопрос... не надо делать бесконечных циклов, циклы должны быть управляемые... как только цикл обработки сообщений принял сообщение на выход, то: оба потока выйдут из циклов и корректно завершатся... после чего можешь освобождать память либо вручную, либо c помощью FreeLibrary...
Rel Достаточно одного цикла и одного потока. Совместить рабочий цикл с циклом выборки сообщений за счёт PeekMessage. Соответственно никаких разделяемых переменных в случае управления сообщениями не нужно. После отправки сообщения (или альтернативно — установки переменной-переключателя) из DLL_PROCESS_DETACH ожидать на хэндле потока, который был сохранён при создании потока из DLL_PROCESS_ATTACH.
да... согласен... на детаче можно эту переменную переключить, тогда вообще не обязательно обрабатывать сообщения, и следовательно не нужно делать гуевым поток-обработчик сообщений... просто предложенный мною метод дает некую гибкость управления dll извне процесса...
to Rel Объясните пожалуйста вот это Код (Text): HANDLE hShutdownEvent = NULL; HANDLE hThreadMainConn = NULL; DWORD WINAPI Thread_func(LPVOID param) { DWORD nEvent; while(1) { nEvent = WaitForMultipleObjects(1,&hShutdownEvent,FALSE,100); if(nEvent == 0) { break; } //....... code } ExitThread(0); return 0; } int __stdcall DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { DWORD dwIDMainConn; hShutdownEvent = CreateEvent(NULL,FALSE,FALSE,NULL); hThreadMainConn = CreateThread(NULL,0,&Thread_func,NULL,0,&dwIDMainConn); break; } case DLL_PROCESS_DETACH: { SetEvent(hShutdownEvent); CloseHandle(hShutdownEvent); CloseHandle(hThreadMainConn); break; } } return 0x01; } и вызов с екзе Код (Text): HMODULE hModule = LoadLibraryA("MyDll.dll"); Sleep(10*1000); FreeLibrary(hModule); после FreeLibrary(hModule); если (в отладчике ) ошибка если просто запускаю екзе после FreeLibrary(hModule); екзе работает несколько минут после чего завершается
984259h Странно, а должен 10 секунд А какой отладчик. Возможно надо еще либо подождать (поставить Sleep между Set и Close, либо SwitchToThread), либо создать цикл ожидания обработки установленного Event т.к. под отладчиком может не произойти переключения потоков, особенно в пошаговом режиме