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.多个回调函数是依次调用的,只有上一个回调函数结束才会开始下一个回调函数

 

posted @ 2021-05-15 23:37  乘舟凉  阅读(378)  评论(0编辑  收藏  举报