LoadLibraryA 方法在超过 1000 次加载/卸载循环后返回错误代码 1114 (ERROR_DLL_INIT_FAILED)

发布于 2024-09-05 22:03:24 字数 881 浏览 4 评论 0原文

我正在使用 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 时发生访问冲突”。

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

I'm programing on C++, I'm using Visual Studio 2008, Windows XP, and I have the following problem:
My application, that is a DLL that can be used from Python, loads an external dll, uses the required methods, and then unloads this external Dll.
It's working properly, but after more than 1000 cycles the method "LoadLibraryA" returns a NULL reference.

The main steps are:

HINSTANCE h = NULL;
h = LoadLibraryA(dllfile.c_str());
DWORD dw = GetLastError(); 

The error got is:

ERROR_DLL_INIT_FAILED
1114 (0x45A) A dynamic link library (DLL) initialization routine failed.

The Dll is unloaded by using the following:

FreeLibrary(mDLL);
mDLL = NULL;

Where mDLL is defined like this:

HINSTANCE mDLL;

First alternative tried:
Just load the Dll only once, and unloaded it when the application ends. This fix the problem but introduces a new one.

When the application ends, instead of first executing the DllMain method of my applicaion, wich unloads the external DLL, is executing first the DllMain method of the other Dll. This cause the following error because my application is trying to unload a Dll that was unload by itself previously.

"Unhandled exception at 0x04a00d07 (DllName.DLL) in Python.exe: 0xC0000005: Access violation reading location 0x0000006b".

Any suggestion will be welcomed.
Thanks in advance.
Regards.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

多像笑话 2024-09-12 22:03:24

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

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

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

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

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

Make sure that initialization code of the loaded/unloaded library doesn't leak memory. Many libraries expect to be loaded only once and not always clean up their resources properly.

E.g. in C++ file at the top level one can declare and initialize a variable like this:

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

The code would be executed when library is loaded automatically. Yet, now, it is impossible to free the hanging instance as library doesn't know precisely when/how it is going to be unloaded. In the case one can either replace "AClass *a" with "AClass a" or write your own DllMain for the library and free resources on DLL_PROCESS_DETACH.

If you have no control over the library's code, then it might make sense to create a cache of loaded libraries and simply never unload them. It is very hard to imagine that there would be unlimited number of libraries to overload such cache.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文