0

如何在 DLLMain 中启动线程意味着 std :: thread - 从根本上说。No 表示 WinApi,STL 表示。当我在流程中运行该函数时,我会从该 DLL 调用应用程序崩溃。先感谢您。

此代码获取文件 (exe) 上的哈希和并将其写入文件。(* 。文本)。但是应用程序崩溃

void initialize()
{
    string buffer;
    thread t(calclulateHash, ref(buffer));
    t.detach();
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            initialize();
            break;
        }
    }
    return true;
}
4

2 回答 2

3

DllMain() 有一些限制。

您不应该在 DllMain 中进行任何阻塞调用,因为它是从 OS 加载程序调用的。锁定加载程序可能会阻止某些线程启动,并且通常会导致坏事。任何形式的锁定。如果您尝试获取当前由需要操作系统加载程序锁的线程持有的锁(您在执行时持有该锁),在最佳情况下您将死锁。不允许启动线程,因为当您启动线程时..您通过操作系统加载程序再次调用此 DllMain,但现在使用 DLL_THREAD_ATTACH 参数。导致同样死锁或非法并发访问该模块未初始化的内存。

明确禁止调用 LoadLibrary/LoadLibraryEx,因为这需要操作系统加载程序锁定。其他对 kernel32 的调用很好,你不能调用 User32。并且不要使用 CRT 内存管理(除非你是静态链接的),任何调用动态 C 运行时的东西——改用 HeapAlloc 和类似的 API。否则,您将调用 SxS 运行时库。您也无法读取注册表。任何跨二进制调用都是 UB,您调用的二进制可能尚未初始化或尚未使用。

祝你今天过得愉快。

于 2016-12-28T02:39:01.597 回答
0

1 DllMain -> 2 新线程 -> 3 再次使用 DLL_THREAD_ATTACH 调用 DllMain -> 4 不检查,所以再次新线程 -> 5 再次使用 DLL_THREAD_ATTACH 调用 DllMain;就像第 3 步一样;

于 2016-12-28T03:08:39.007 回答