程序加载独立目录下的dll(loadlibraryex,setdlldirectory,setcurrentdirectory用法)

来源:互联网 发布:淘宝美工月薪多少 编辑:程序博客网 时间:2024/06/07 06:21

很多时候,第三方库拥有较多的相关组件,为了使程序安装目录看起来更有调理(或者存在不同目录的应用程序都会引用这些组件),往往希望这些依赖的组件放到统一的目录中,方便管理和查看问题。这种应用场景,带来了一个的问题,即如何改变dll的搜索路径,从而保证程序可以找到正确的dll。

常用的方法包括以下三种:

1. loadlibraryex,提供了参数LOAD_WITH_ALTERED_SEARCH_PATH,可以从用户指定的地址加载dll

2. setdlldirectory, 修改dll的默认查找路径。

3. setcurrentdirectory, 修改程序的工作目录。 

三种方法各显神通地解决了这个问题,但解决的方法各有不同,下面说说各自的特点和注意事项。

第一种方法,个人首推的一种方法,特点是可以不需要调用额外的api即可以完成dll的载入,调用时,系统会自动从用户指定的路径进行搜索,替换标准的从进程运行路径进行搜索,接下来的搜索路径与标准搜索路径相同。需要注意的是所加载dll的依赖模块也会按照这种方式进行搜索。但是有一种场景,使用这种方式就无法满足,例如加载a.dll,a.dll会延迟加载b.dll,调用该方法,会让a.dll加载成功,但当使用b.dll方法时,会发现b.dll是加载失败的。当然,不建议第三方库使用这种延迟加载的方法(除非考虑到效率等,虽然延迟加载的另外一个好处是可以用于兼容dll版本,但仍然不提倡在依赖库中使用这种方式),可以使用动态加载的方式载入dll,在载入时不依赖使用者的dll查找顺序。

第二种方法,一般会和loadlibrary配合使用,搜索路径会优先在程序加载路径开始,然后搜索selldlllibrary所引入的路径。但是很遗憾setdlldirectory最低可使用的windows版本是winxp sp1,虽然winxp已经光荣退役了,但估计目前该系统依然占据了很多用户的桌面,在很长一段时间内,要考虑兼容这些用户。另外使用这种方式并不是线程安全的(不过这一点可以由调用程序来保证)。还有一点提醒,在调用该函数后,最好记住恢复默认dll搜索路径,即调用setdlldirectory(null),以免影响其他dll载入。

第三种方法,改变了进程的当前目录,dll加载时,依然按照默认搜索路径进行,但是由于进程当前路径已经被改变,因此搜索的第一站就变为我们传入的路径了,但是这种调用会产生副作用,而且当需要使用的dll完成载入后,一定要将程序当前路径设回,否则会影响其他功能的使用。因此建议慎重使用,而且前两种方法已经可以解决几乎所有的dll载入问题了。


具体api可参照msdn,推荐一篇关于dll搜索顺序的msdn说明:http://msdn.microsoft.com/en-us/library/ms682600(v=vs.85).aspx


0 0
原创粉丝点击