DLL中的CreateThread过早终止



我正在尝试从控制台应用程序加载DLL。简单的控制台应用程序如下所示:

#include <iostream>
#include <windows.h>
int main(){
HMODULE handleDll = LoadLibraryA("C:\Tools\TestDLL.dll");
if (handleDll)
{
std::cout << "DLL Loaded at Address: " << handleDll << std::endl;
}
FreeLibrary(handleDll);
}

DLL应该是一个POP消息框,但它只是在屏幕上闪烁,而不是等待用户输入。DLL代码如下:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>
DWORD WINAPI ThreadProc( __in  LPVOID lpParameter )
{
MessageBox(NULL, L"Hi From The Thread!", L"Pop a Box!", MB_OK);
return 0;
}
extern "C" __declspec(dllexport) 
VOID PopMessageBox()
{
DWORD ThreadID;
HANDLE handleThread; 
handleThread = CreateThread(NULL, 0, ThreadProc, 0, 0, &ThreadID);
CloseHandle(handleThread);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD  ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
PopMessageBox();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

我的问题是…如何使线程函数中的代码完全执行,而不会过早终止或导致痛苦的死锁?为我不完美的英语和缺乏经验而道歉。

原因是您在DllMain中执行了不安全的操作:您正在调用CreateThread

您在DllMain中对流程附加的响应非常有限,文档中指出了这一事实:

在DLL入口点中可以安全地执行的操作有很大的限制。有关在DllMain中调用不安全的特定Windows API,请参阅常规最佳实践。如果您需要除最简单的初始化之外的任何东西,请在DLL的初始化函数中执行。您可以要求应用程序在运行DllMain之后以及调用DLL中的任何其他函数之前调用初始化函数。

警告将您链接到";一般最佳实践";其中对";[c] 所有CreateThread。如果不与其他线程同步,创建线程可以工作,但这是有风险的">

即使没有与其他线程同步的风险,该代码在其他方面也很脆弱:例如,您的main只需调用FreeLibrary即可退出。你在DLL中生成的线程,可能实际上是在执行中期,将有它应该运行的代码未映射。你真是在把地毯从下面扯出来!