F
FreeAndNil
Unregistered / Unconfirmed
GUEST, unregistred user!
以下说明,估计大家都熟悉:>>动态链接库简介 >>动态链接库(DLL,即 “Dynamic-Link Library”)是一个能够被应用程序和其它的DLL调用的过程和函数的集合体,它里面包含的是公共代码或资源。DLL是Windows的基石,所有的Win32 API函数都包含在DLL中。 >>使用DLL有许多优点: >>1、一个DLL可以提供给不同的程序使用,如果有多个程序使用相同的DLL,也只需将DLL在内存中装载一次,这样就节省了内存开销。 >>......最近写代码发现个问题,这个优点1,现在看来是有点问题。照理说,一个dll,无论通过什么方式加载(静态、动态),在内存中,都应该只加载一次,卸载时,如果有一个加载的程序没有卸载dll,这个dll都应该仍然在内存中,直到所有使用者卸载了dll,但是我写了段代码,发现事实却不是这样。代码很简单,主程序exe,加载了动态库:dll3、dll4,这两个dll都加载了dll2,并在窗体中调用dll2的一个函数显示一个公用窗体,为简单,dll3、dll4就直接用静态连接的方式加载了dll2,结果发现,当dll3、dll4的窗体都打开了dll2中的公用窗体,然后卸载dll3或dll4中的一个(卸载时会调用dll2中的释放窗体函数去释放窗体),主程序马上崩溃,另外一个现象是,dll3、dll4两个窗体打开,然后dll4个调用dll2中函数打开公用窗体,然后卸载dll4,这时在dll3的窗体中,调用dll2的函数去打开公用窗体,会报地址错误。手头没有其他工具,就用360->高级->系统进程状态功能,查看这个exe加载dll的情况,一看,发现了奇怪现象,加载dll3(其中静态加载dll2),结果360显示,dll2被加载了两次,然后再加载dll4(其中静态加载dll2),dll2没有再次被加载,卸载dll4,发现,exe进程中的两个dll2都被卸载了,也就是说,虽然dll3仍然在内存中,但dll3静态加载的dll2,却已经被从内存中卸载了,所以才有了上面两个现象:1、此时在dll3中调用dll2的函数,报地址错误,当然了,dll都卸载了;2、如果卸载dll4之前,dll3已经调用dll2中的函数打开了窗体,那么在卸载dll4后,主程序崩溃。解决方法很简单,就是用在dll3、dll4中LoadLibrary动态加载dll2,这时用360工具去看进程加载dll的情况,就完全和前面说的一样,dll3、dll4加载了dll2,内存中只看到dll2加载了一次,卸载dll3、dll4中的一个,dll2仍然在内存中,直到所有加载dll2的dll全部从内存卸载,dll2才从内存中卸载。这个现象怎么解释?静态加载dll为什么会有这样的问题?麻烦各位高手给我解下惑。补充一句,我用的是delphi6。