1

我在 C++ 上编程,我使用的是 Visual Studio 2008、Windows XP,但我遇到了以下问题:我的应用程序是一个可以从 Python 使用的 DLL,它加载了一个外部 dll,使用了所需的方法,并且然后卸载这个外部 Dll。它工作正常,但经过 1000 多次循环后,方法“LoadLibraryA”返回一个 NULL 引用。

主要步骤是:

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,并在应用程序结束时将其卸载。这解决了问题,但引入了一个新问题。

当应用程序结束时,不是首先执行我的应用程序的 DllMain 方法,它卸载外部 DLL,而是首先执行另一个 Dll 的 DllMain 方法。这会导致以下错误,因为我的应用程序正在尝试卸载以前自行卸载的 Dll。

“Python.exe 中 0x04a00d07 (DllName.DLL) 处的未处理异常:0xC0000005:访问冲突读取位置 0x0000006b”。

任何建议都将受到欢迎。提前致谢。问候。

4

1 回答 1

1

确保加载/卸载库的初始化代码不会泄漏内存。许多库只希望加载一次,并不总是正确地清理它们的资源。

例如,在顶层的 C++ 文件中,可以声明和初始化一个变量,如下所示:

AClass *a = new AClass(1,2,3);

代码将在库自动加载时执行。然而,现在不可能释放挂起的实例,因为库不能准确地知道何时/如何卸载它。在这种情况下,可以将“AClass *a”替换为“AClass a”,或者为库编写自己的DllMain并在 DLL_PROCESS_DETACH 上释放资源。

如果您无法控制库的代码,那么创建已加载库的缓存并且永远不卸载它们可能是有意义的。很难想象会有无限数量的库来超载这样的缓存。

于 2010-06-10T22:31:04.393 回答