Как запустить поток в DLLMain?

Как я могу начать поток в DLLMain означает, что std:: thread - принципиально. Не значит 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;
}

2 ответа

Есть ограничения на DllMain().

Вы не должны делать никаких блокирующих вызовов в DllMain, потому что он вызывается из загрузчика ОС. Блокировка загрузчика может помешать запуску какого-либо потока и, как правило, приводит к плохим вещам. Блокировка любого вида. Если вы пытаетесь получить блокировку, которая в данный момент удерживается потоком, который нуждается в блокировке загрузчика ОС (которую вы удерживаете во время выполнения из нее), в лучшем случае вы будете тупиковой. Запуск потоков не разрешен, потому что когда вы запускаете поток, вы вызываете этот DllMain снова через загрузчик ОС, но теперь с параметром DLL_THREAD_ATTACH. Это приводит к тому же тупику или незаконному параллельному доступу к неинициализированной памяти этого модуля.

Вызовы LoadLibrary/LoadLibraryEx явно запрещены, поскольку для этого требуется блокировка загрузчика ОС. Другие вызовы в kernel32 в порядке, вы не можете вызвать User32. И не используйте управление памятью CRT (если только вы не связаны статически), вообще ничего, что вызывает динамическое выполнение C - используйте вместо этого HeapAlloc и аналогичный API. В противном случае вы вызовете библиотеку времени выполнения SxS. Вы также не можете прочитать реестр. Любые кросс-двоичные вызовы - это UB, двоичный файл, в который вы звонили, возможно, не был инициализирован или уже не использовался.

Хорошего дня.

1 DllMain -> 2 Новый поток -> 3 снова вызвать DllMain с DLL_THREAD_ATTACH -> 4 без проверки, поэтому Новый поток снова -> 5 снова вызвать DllMain с DLL_THREAD_ATTACH; так же, как шаг 3;

Другие вопросы по тегам