Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在DLLMain中启动线程?_C++_Multithreading_C++11_Dll_Dllmain - Fatal编程技术网

C++ 如何在DLLMain中启动线程?

C++ 如何在DLLMain中启动线程?,c++,multithreading,c++11,dll,dllmain,C++,Multithreading,C++11,Dll,Dllmain,如何在DLLMain中启动线程意味着std::thread-从根本上说。No表示WinApi,STL表示。当我在流中运行该函数时,我会使从该DLL调用的应用程序崩溃。先谢谢你 此代码获取文件(exe)的哈希和,并将其写入文件。(*.txt)。但是应用程序崩溃了 void initialize() { string buffer; thread t(calclulateHash, ref(buffer)); t.detach(); } BOOL WINAPI DllMain

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

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

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;
}

DllMain()有一些限制

您不应该在DllMain中执行任何阻塞调用,因为它是从OS loader调用的。锁定加载程序可能会阻止某些线程启动,通常会导致不好的结果。任何类型的锁定。如果您试图获取当前由需要OS loader锁的线程持有的锁(从该线程执行时,您正在持有该锁),那么在最佳情况下,您将死锁。不允许启动线程,因为当您启动线程时。。您可以通过OS加载器再次调用此DllMain,但现在使用DLL\u THREAD\u ATTACH参数。它会导致相同的死锁或非法并发访问此模块的未初始化内存

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


祝你度过愉快的一天。

DllMain()有一些限制

您不应该在DllMain中执行任何阻塞调用,因为它是从OS loader调用的。锁定加载程序可能会阻止某些线程启动,通常会导致不好的结果。任何类型的锁定。如果您试图获取当前由需要OS loader锁的线程持有的锁(从该线程执行时,您正在持有该锁),那么在最佳情况下,您将死锁。不允许启动线程,因为当您启动线程时。。您可以通过OS加载器再次调用此DllMain,但现在使用DLL\u THREAD\u ATTACH参数。它会导致相同的死锁或非法并发访问此模块的未初始化内存

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


祝你度过愉快的一天。

<1 DllMain->2个新线程->3使用DLL\u thread\u ATTACH再次调用DllMain->4而不检查,因此再次使用新线程->5使用DLL\u thread\u ATTACH再次调用DllMain;就像步骤3

1 DllMain->2 New thread->3使用DLL\u thread\u ATTACH再次调用DllMain->4而不检查,因此再次新线程->5使用DLL\u thread\u ATTACH再次调用DllMain;就像步骤3

那么,在DLLMain中使用std::thread是否可能是“神奇”的方式呢?或者是CreateThread(windows api)@user230568的唯一选项,您不能在那里创建线程。。CreateThread是内核32,但不能导致OS加载程序的递归。制作一个导出函数来完成额外的初始化,从你的应用程序中调用它,相当多的API DLL都会这样做。如果需要,请使DLL的其他功能在该调用之前不起作用。或者,更好的方法是,尝试模拟第一次调用DLLstd::thread时创建的单例。thread并不神奇。在底层,它使用操作系统线程支持,所以它也是被禁止的。我想,无论是谁在不了解它是如何工作的情况下使用它,它都是神奇的。你知道,成功的先进技术…@Swift-See。在
DllMain()
中自己调用
CreateThread()
是安全的(只是不推荐),但等待线程是不安全的。只要调用
CreateThread()
后退出
DllMain()
,就不会发生死锁。那么,在DllMain中使用std::thread是否可能实现“神奇”的方式呢?或者是CreateThread(windows api)@user230568的唯一选项,您不能在那里创建线程。。CreateThread是内核32,但不能导致OS加载程序的递归。制作一个导出函数来完成额外的初始化,从你的应用程序中调用它,相当多的API DLL都会这样做。如果需要,请使DLL的其他功能在该调用之前不起作用。或者,更好的方法是,尝试模拟第一次调用DLLstd::thread时创建的单例。thread并不神奇。在底层,它使用操作系统线程支持,所以它也是被禁止的。我想,无论是谁在不了解它是如何工作的情况下使用它,它都是神奇的。你知道,成功的先进技术…@Swift-See。在
DllMain()
中自己调用
CreateThread()
是安全的(只是不推荐),但等待线程是不安全的。只要调用
CreateThread()
后退出
DllMain()
,就不会发生死锁。这是什么“意味着/没有意味着/没有意味着”的东西?这是什么“意味着/没有意味着/没有意味着”的东西?他实际上在那里得到了检查,但1 DllMain->2个新线程->3使用DLL\u thread\u ATTACH再次调用DllMainpossible@Swift是的,有可能,前提是允许先退出
DLL\u进程\u附加
。他实际上在那里得到了检查,但1 DllMain->2 New thread->3在DLL\u thread\u附加的情况下再次调用DllMainpossible@Swift是的,这是可能的,前提是允许先退出
DLL\u PROCESS\u ATTACH