c++ - DLL卸载程序

标签 c++ dll

我确实解决了眼前的问题,但现在我需要了解解决问题的原因。 ;-)

所以我还有几个问题。

假设我有一个从 DLL 导出的类。现在这个 DLL 应该在我每次调用时加载到内存中:

MyExportedClass *pb = new MyExportedClass;

它应该保留在内存中,只有在我调用时才会卸载:

delete pb;

这是正确的吗?

如果我理解正确并且上一个问题的答案是肯定的,那么在下面的场景中应该会发生什么:

我有一个从 dll (dll1) 导出的接口(interface),我有一个从另一个 dll (dll2) 导出的实现。所以每次我执行:

MyInterface *pInterface = new MyImplementation;

这两个 dll 都应该加载到内存中,并且它们应该保留在内存中直到我调用:

delete pInterface;

这是正确的吗?

现在,如果这个问题的答案是肯定的——我是否有控制权/说法,哪个库将首先被卸载,哪个将是第二个?或者卸载总是在调用相应类的析构函数之后立即发生?

现在,有没有一种工具可以检查库是否卸载以及卸载的时间?我可能只使用伪造的 DllMain() 并检查其 process_detach 情况,但我的印象始终是:在库导出函数时使用 DllMain,而在库导出类时不使用 DllMain。我从 MSVC 5/6 开始就使用了这种方法(遵循其中一本关于 C++ 的书籍)。

我错了吗?在这两种情况下我仍然可以使用 DLLMain 吗?

谢谢。

最佳答案

DLL 加载可以是自动的(如果在导入表中列出)或手动的(使用 LoadLibrary)。某些托管框架(如 .NET)会在其元数据中看到 DLL 导入声明时静默地为您调用 LoadLibrary,但 C++ 不是其中之一。 C++ 最接近的东西是延迟加载,其中调用 LoadLibrary 的函数(默认情况下,您可以替换自己的函数)由编译器提供。

另一方面,DLL 卸载始终是手动的。删除对象永远不会隐式卸载 DLL。您必须调用 FreeLibrary(或 FreeLibraryAndExitThread)。当该库中定义的对象仍在使用时,您最好不要调用 FreeLibrary

现在,Windows 中的 COM 系统有点复杂,因为它为您管理 DLL 生命周期。但是 DLL 生命周期仍然不受对象删除控制,而是通过调用 DLL 中的 DllCanUnloadNow 函数来控制。通常您需要维护事件对象的数量才能正确编写该函数。但它仍然需要您手动实现,并且您可以简单地始终返回 false 以永不卸载(这在开发过程中有点痛苦,因为您必须关闭整个应用程序才能尝试新的插件版本等......但实际上释放无论如何,每次使用 DLL 并成功卸载它都是罕见的)

当然,没有任何东西会自动卸载导入表中列出的 DLL,无论创建或销毁多少对象实例,它们都会在进程启动期间加载并且永远不会卸载。

关于c++ - DLL卸载程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36749092/

相关文章:

c++ - MySQL 连接器 C++ 未解析的外部符号

c++ - 从 MSVC 32 位版本解码程序集(作业)。无操作有什么作用?

winapi - 在64位应用程序中加载32位DLL库

c++ - : Native DLL, UWP DLL 和 C++/CLI DLL 之间的区别

python - 在线运行 ASP 脚本时的安全权限

c++ - 在 std::move() 之后删除堆上的结构成员

c++ - 许多小分配的最有效 malloc 实现?

c++ - 为什么 cout.put() 在流中不能正常工作?

c++ - 如何在 DLL(动态链接库)中运行 MPI

Python ctypes : How do I flush output from stderr?