从Windows 7中的另一个DLL加载dsound.dll时出现崩溃。以下代码崩溃:
#include <Windows.h>
#include <mmreg.h>
#include <dsound.h>
#include <assert.h>
HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext);
HMODULE hDsound;
BOOL CALLBACK DSEnum(LPGUID a, LPCSTR b, LPCSTR c, LPVOID d)
{
return TRUE;
}
void CrashTest()
{
HRESULT hr;
hDsound = LoadLibraryA("dsound.dll");
assert(hDsound);
*(void**)&pDirectSoundEnumerateA = (void*)GetProcAddress(hDsound, "DirectSoundEnumerateA");
assert(pDirectSoundEnumerateA);
hr = pDirectSoundEnumerateA(DSEnum, NULL);
assert(!FAILED(hr));
}
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hModule);
CrashTest();
}
}
使用此错误代码:
Unhandled exception at ... in ...: 0xC0000005: Access violation reading location 0x00000044.
(由于某种原因它总是0x44)。它适用于Windows XP或直接从.exe加载(而不是从单独的DLL加载)。救命!?! :)
答案 0 :(得分:3)
永远不要从LoadLibrary
致电DllMain
。来自documentation:
入口点功能应该只执行简单的初始化或终止任务。它不能调用LoadLibrary或LoadLibraryEx函数(或调用这些函数的函数),因为这可能会在DLL加载顺序中创建依赖循环。这可能导致在系统执行其初始化代码之前使用DLL。类似地,入口点函数在进程终止期间不得调用FreeLibrary函数(或调用FreeLibrary的函数),因为这可能导致在系统执行其终止代码后使用DLL。
相反,您可以创建并导出初始化函数,并在加载DLL后调用它。