有没有办法编写一个在卸载DLL时调用的函数?我能想到的一件事是在我的DLL中创建一个全局对象,并在其析构函数中编写无内存调用
这是可能的,虽然我完全相信你的对象的析构函数将被调用时将是未定义的.
您可能感兴趣DLL_PROCESS_DETACH
,虽然您应该避免做任何重要的事情DllMain
,但似乎可以接受解除分配资源.请注意警告:
当由于DLL加载失败,进程终止或对FreeLibrary的调用而从进程卸载DLL时,系统不会使用DLL_THREAD_DETACH值调用DLL的入口点函数.这个过程.该DLL仅发送DLL_PROCESS_DETACH通知.DLL可以利用这个机会清理DLL已知的所有线程的所有资源.
当处理DLL_PROCESS_DETACH,一个DLL应释放的资源,例如仅当DLL被动态地卸载(在lpReserved参数是NULL)堆存储器.如果进程正在终止(lpvReserved参数为非NULL),则除当前线程之外的进程中的所有线程已经退出或已通过调用ExitProcess函数显式终止,这可能会留下一些进程资源,例如堆处于不一致的状态.在这种情况下,DLL清理资源是不安全的.相反,DLL应该允许操作系统回收内存.
您可能需要详细说明 DLL 为什么能够保存到内存中,如果DLL创建了大量对象,它们应该具有已定义的生命周期并在其生命周期结束时自行清理.
如果它们不是对象(即内存被分配并通过函数返回给调用者),为什么不将责任归还给使用DLL的人?他们可以释放记忆.终端服务库遵循此模式(WTSFreeMemory
).
如果资源是长期存在的并且必须在库的生命周期内存在,那么让使用者控制库的生命周期.写两个函数:MyFrameworkStartup
并MyFrameworkShutdown
酌情.Winsock遵循这种模式(WSAStartup
和WSACleanup
).
我的另一个想法是在DLL卸载时依靠操作系统来释放内存,但这看起来很脏.
不要担心释放记忆; 当进程地址空间被破坏时,它将全部消失.不要担心关闭手柄; 当进程句柄表被销毁时,句柄会自动关闭.不要试图调用其他DLL,因为那些其他DLL可能已经收到了他们的DLL_PROCESS_DETACH通知,在这种情况下,如果你试图在析构函数运行后尝试使用它,它们的行为可能与Delphi对象行为不正常的行为不同.
在实施"无所事事"策略之前,请务必阅读整篇文章和评论并理解它.
归档时间: |
|
查看次数: |
9363 次 |
最近记录: |