关于API的DLL的搜索顺序问题

来源:互联网 发布:sql经典50题 编辑:程序博客网 时间:2024/05/29 16:25

   在调试应用端程序时,偶然发现很奇怪的现象,是关于被引用的MFC扩展DLL的使用问题,跟踪了老半天,总算找到问题所在,同时,也解除了以前存于心中的疑感,问题虽小,但很可能被忽视。

问题:
    将OCX与依赖的DLL置于同一目录下,并注册该OCX,这能保证使用正确吗?
   初一看,感觉是这么回事,实则不然。

我们来模拟一下场景:
    假设控件A.ocx,控件 B.ocx,都依赖于MFC的扩展 DLL C.dll.(非组件,纯API DLL)

一般的应用场景:
    A.ocx B.ocx c.dll都部署于同一目录(Release_Dir),将该目录下的A,B控件注册。
应用程序:在同一进程中调用 A控件和B控件.A先于B被加载. 注意:A先于B加载。
   好了,某一天,B控件升级了,为了实现新功能,C.dll也相应做了变更。
   然后,为了方便测试,开发人员在自已的新目录(Code_Dir)下将新的B.ocx注册了,新的c.dll也在Code_Dir下。有问题吗?呵呵,有时有问题,有时没问题。
   试试我们的应用程序,发现:新的B控件并不能正确引用到新的C.dll,似乎引用到的仍然是旧的DLL。 
   Why? 
  原因很简单:我们的应用中,A控件先于B被加载,于是,旧的C.dll先被加载了,当加载B时,它只好引用旧的C.dll。轻者:B的新功能不能起作用, 重者:程序会发生大的异常。

总结:
    我们有时候在检查应用开发人员机器上的控件时,基本的判定准则是:我要检查的最新注册的控件的是新的,它的依赖DLL在同一目录下,也是新的,于是,就万事大吉了。嘿,那就可能错了噢。
所以呢:在检测应用开发人员机器上控件或引用DLL的新旧时,保险的做法:如果不能确定应用端在本应用中用到了哪些控件,那就把依赖于该DLL的所有控件全部置于同一目录,然后全部重新注册。或者,当然,你可以让你的DLL在该机器上只有一份(这有点难,呵)

我们引申一下:
对于 API的DLL的搜索顺序:
如果是采用lib方式隐式链接的话:
1:被装载程序包的执行目录。
2:当前目录。如果与执行目录不同的话。
3:Windows系统目录
4:Windows目录。
5:Path中的目录。

这应该是固定的一种规则。
通过上述的分析,实际上我们应该再添加一个0优先级。
0:当内存中已有该DLL时,不会再去搜索任何的物理目录。也就是说,进程中内存映射中的最优先。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tiger119/archive/2006/04/07/654857.aspx