程序加载独立目录下的dll(loadlibraryex,setdlldirectory,setcurrentdirectory用法)
2016-06-27 19:52
246 查看
很多时候,第三方库拥有较多的相关组件,为了使程序安装目录看起来更有调理(或者存在不同目录的应用程序都会引用这些组件),往往希望这些依赖的组件放到统一的目录中,方便管理和查看问题。这种应用场景,带来了一个的问题,即如何改变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
常用的方法包括以下三种:
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
相关文章推荐
- MYSQL添加一列具体步骤
- 遇到Could not load file or assembly ... or one of its dependencies怎么办
- GibbsLDA constants.h分析
- HDU 2108 Shape of HDU(凸包)
- Codewars 打怪日记 5星级kyu 数独游戏 我是否完成了数组 Did I Finish my Sudoku? 看小菜和大神循环的巧妙运用
- 获取沙盒路径
- 十二.定时器
- UDT中epoll对CLOSE状态的处理
- oracle 常用相关sql 语句
- 【JZOJ 3466】 选课 select
- 城市轨道交通信号与通信系统
- MD5加密字符串,返回加密后的字符串
- Fast RCNN
- git版本管理工具
- 小技巧-解决"此图片来自微信公众平台,未经允许不可引用"
- 十.媒体播放
- poj2104(K-th Number)
- avalon2学习教程15指令总结
- 用UIWebView来显示动态图片
- 线程的私家小院儿:ThreadLocal