新人求助:为什么tls函数 执行会报错啊?
#include <Windows.h>#include <iostream>
#pragma comment(linker,"/INCLUDE:__tls_used")
using namespace std;
void NTAPI t_TlsCallBack_A(PVOID DllHandle, DWORD Reason, PVOID Reserved) {
cout << "TLS回调函数执行了,原因: " << Reason << endl;
}
#pragma data_seg(".CRT$XLX")
PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { t_TlsCallBack_A,0 };
#pragma data_seg()
DWORD WINAPI ThreadProc(LPVOID lPram) {
cout << "开始" << endl;
return 0;
}
int main(void)
{
HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
if (hThread != 0) {
WaitForSingleObject(hThread, -1);
CloseHandle(hThread);
}
return 0;
}
为什么编译器运行后会报:严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息
错误 LNK2001 无法解析的外部符号 __tls_used TLS回调函数反调试 D:\c++\vs2019-practice\TLS回调函数反调试\TLS回调函数反调试\TLS回调函数反调试.obj 1
是我写的哪里有问题吗? 这段代码中,展示了如何在Windows平台上使用线程局部存储(TLS, Thread Local Storage)回调函数的设置和使用。但是,有几个地方需要注意或可能需要调整以确保代码能按预期工作。
1. **TLS回调函数和线程创建**:
- 代码中定义了一个TLS回调函数`t_TlsCallBack_A`,该函数会在线程创建、终止或线程数据被销毁时调用(取决于`Reason`参数)。
- 使用了`#pragma data_seg`来指定一个特定的段(`.CRT$XLX`),这是用于存放指向TLS回调函数的指针数组。这是必要的,因为Windows加载器会查找这个段来获取TLS回调函数的列表。
- 然而,虽然定义了TLS回调函数,但代码中没有显式地将DLL(或EXE,在这个例子中是EXE)与TLS回调相关联。通常,这是通过修改PE(Portable Executable)文件的头部或使用编译器/链接器选项来完成的。在这段代码中,由于是在EXE中直接使用,并且使用了`#pragma comment(linker,"/INCLUDE:__tls_used")`来确保链接器不会优化掉TLS相关的段,这是足够的。
2. **线程创建**:
- 使用`CreateThread`创建了一个线程,该线程执行`ThreadProc`函数。但是,`ThreadProc`函数中并没有使用TLS相关的任何功能(如`TlsGetValue`、`TlsSetValue`等)。因此,虽然TLS回调函数被定义并可能被触发(特别是在线程创建时),但在`ThreadProc`内部并没有看到TLS的实际使用。
3. **输出**:
- `cout`在多线程环境中可能不是线程安全的,尤其是在没有额外同步的情况下。虽然在这个特定的例子中,由于`WaitForSingleObject`等待线程结束后再继续,所以`cout`的使用可能是安全的,但在更复杂的场景中应该注意。
4. **错误处理**:
- `CreateThread`调用后,应该检查返回的句柄是否为`NULL`(或`INVALID_HANDLE_VALUE`,但在Windows API中,`CreateThread`实际上返回`NULL`来表示错误),并处理可能的错误情况。
5. **代码风格和可读性**:
- 代码中使用了中文注释,这可能在非中文环境下造成理解上的障碍。建议使用英文注释以提高代码的可读性和可维护性。
总结来说,这段代码展示了如何在Windows平台上设置TLS回调函数,但并未在创建的线程中使用TLS。此外,还需要注意多线程环境中的输出同步和错误处理。 你编译的是x86还是x64?
#ifdef _WIN64
#pragma comment(linker, "/INCLUDE:_tls_used")
#pragma comment(linker, "/INCLUDE:tls_callback_func")
#else
#pragma comment(linker, "/INCLUDE:__tls_used")
#pragma comment(linker, "/INCLUDE:_tls_callback_func")
#endif
页:
[1]