Хорошо. Для Windows Vista и выше, как сказал Джеймс Макнеллис, мы могли бы использовать FlsCallback.
Для DLL мы могли бы просто использовать DllMain, если параметр Reason равен DLL_THREAD_DETACH, мы делаем очистку. Альтернативой может быть использование _pRawDllMain, это похоже на другой DllMain, вы можете найти его на источник продвижения.
Для EXE мы могли бы использовать обратный вызов TLS, посмотрите здесь и здесь, и, конечно же, источник ускорения. На практике это работает в Windows XP, но я обнаружил, что оптимизации могут сделать его неэффективным, поэтому будьте осторожны с оптимизациями или делайте явную ссылку на указатель вашей функции обратного вызова.
Сохраните приведенный ниже код в tls.cpp и добавьте его в свой проект, независимо от того, exe это или dll, он будет работать. Обратите внимание, что для DLL в Windows Vista и более поздних версиях функция onThreadExit может быть вызвана дважды — один раз из dll_callback и один из tls_callback.
#include <windows.h>
extern void onThreadExit();
static void NTAPI tls_callback(PVOID, DWORD reason, PVOID)
{
if (reason == DLL_THREAD_DETACH) {
onThreadExit();
}
}
static BOOL WINAPI dll_callback(LPVOID, DWORD reason, LPVOID)
{
if (reason == DLL_THREAD_DETACH) {
onThreadExit();
}
return TRUE;
}
#pragma section(".CRT$XLY",long,read)
extern "C" __declspec(allocate(".CRT$XLY")) PIMAGE_TLS_CALLBACK _xl_y = tls_callback;
extern "C"
{
extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID) = &dll_callback;
}
#pragma comment(linker, "/INCLUDE:__tls_used")
#pragma comment(linker, "/INCLUDE:__xl_y")
Если вы считаете, что это непонятно, используйте at_thread_exit сложность скрыта. Фактически приведенный выше код является упрощенной версией boost tls. И если вы не хотите использовать ускорение, в системе Windows это альтернатива.
Или более общий способ: thread_local.
person
amanjiang
schedule
14.09.2015