C语言注册TLS回调函数
#include <tchar.h> #include <windows.h> #pragma comment(linker,"/INCLUDE:__tls_used") //告诉链接器要使用TLS void print(char * msg){ HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); WriteConsoleA(out,msg,strlen(msg),0,0); } void NTAPI TLS_CALLBACK1(PVOID DLLHandle,DWORD Reason,PVOID REserved){ char buffer[MAX_PATH] = {}; Sleep(1000); wsprintfA(buffer,"TLS_CALLBACK1():DLLHandle=%X, Reason=%d\n",DLLHandle,Reason); print(buffer); } void NTAPI TLS_CALLBACK2(PVOID DLLHandle,DWORD Reason,PVOID REserved){ char buffer[MAX_PATH] = {}; Sleep(1000); wsprintfA(buffer,"TLS_CALLBACK2():DLLHandle=%X, Reason=%d\n",DLLHandle,Reason); print(buffer); } /* 注册TLS函数 但是只规定了回调函数的地址以及函数在那个节区
,#pragma comment(linker,"/INCLUDE:__tls_used")这条语句的作用就是告诉链接器.CRT$XLY里有回调函数的地址,来调用吧
.CRT$XLX的作用 CRT表示使用C Runtime 机制
X表示表示名随机 L表示TLS Callback section
X也可以换成B~Y任意一个字符
*/
#pragma data_seg(".CRT$XLY")
PIMAGE_TLS_CALLBACK callBACKs[] = {TLS_CALLBACK1,TLS_CALLBACK2,0};
#pragma data_seg()
void WINAPI ThreadProc(LPVOID lParam){
print("ThreadProc() start\n");
print("ThreadProc() over\n");
}
void main(){
HANDLE hThread;
print("main() start\n");
hThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)ThreadProc,0,0,0);
WaitForSingleObject(hThread,60*1000);
CloseHandle(hThread);
print("main() end\n");
}
TLS回调具有如下特性:
1.回调函数会在进程启动时,进程结束时,线程启动前,线程结束后,依次触发,并且TLS回调函数结束后,才会运行导致它被触发的主线程或线程
2.回调函数只能阻塞触发它调用的线程,如线程一的TLS回调函数被触发,不会影响主线程。
3.多个回调函数是依次调用的,只有上一个回调函数结束才会开始下一个回调函数