![](/img/trans.png)
[英]DLL CreateThread, DisableThreadLibraryCalls and _beginthreadex
[英]CreateThread in DLL Terminating Prematurely
我正在嘗試從控制台應用程序加載 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 一個 MessageBox,它只是在屏幕上閃爍而不是等待用戶輸入。 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]all CreateThread。如果您不與其他線程同步,創建線程可以工作,但有風險。”
即使沒有與其他線程同步相關的風險,這段代碼在其他方面也很脆弱:例如,你的main
只是簡單地調用FreeLibrary
並退出。 您在 DLL 中生成的線程(實際上可能是執行中)將具有未映射的應該運行的代碼。 你真的把地毯從它下面拉出來了!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.