LoadLibraryA方法在加载/卸载超过1000次后返回错误代码1114 (ERROR_DLL_INIT_FAILED)
我在用C++编程,使用的是Visual Studio 2008和Windows XP,现在遇到了一个问题:
我的应用程序是一个可以被Python调用的DLL,它会加载一个外部的DLL,使用里面需要的方法,然后再卸载这个外部的DLL。这个过程本来是正常的,但在运行超过1000次后,"LoadLibraryA"这个方法返回了一个空值。
主要步骤是:
HINSTANCE h = NULL;
h = LoadLibraryA(dllfile.c_str());
DWORD dw = GetLastError();
出现的错误是:
ERROR_DLL_INIT_FAILED
1114 (0x45A) A dynamic link library (DLL) initialization routine failed.
这个DLL是通过以下方式卸载的:
FreeLibrary(mDLL);
mDLL = NULL;
其中mDLL是这样定义的:
HINSTANCE mDLL;
我尝试的第一个解决办法是:
只加载一次这个DLL,并在应用程序结束时再卸载它。这样解决了之前的问题,但又引入了一个新问题。
当应用程序结束时,首先执行的是其他DLL的DllMain方法,而不是我应用程序的DllMain方法,这样就导致了错误,因为我的应用程序试图卸载一个已经被自己卸载过的DLL。
错误信息是:“在Python.exe中,0x04a00d07(DllName.DLL)发生未处理的异常:0xC0000005:访问冲突,读取位置0x0000006b”。
欢迎任何建议。谢谢!
祝好。
1 个回答
1
确保加载或卸载的库的初始化代码不会造成内存泄漏。很多库只希望被加载一次,而不会总是正确地清理它们的资源。
比如,在C++文件的顶部可以这样声明和初始化一个变量:
AClass *a = new AClass(1,2,3);
这段代码会在库被自动加载时执行。然而,现在很难释放这个悬挂的实例,因为库并不知道它什么时候以及如何会被卸载。如果遇到这种情况,可以把“AClass *a”换成“AClass a”,或者为这个库写一个自己的DllMain,在DLL_PROCESS_DETACH时释放资源。
如果你无法控制库的代码,那么可以考虑创建一个已加载库的缓存,简单地不卸载它们。很难想象会有无限数量的库来超载这样的缓存。