IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> c++同名dll和dll中同名函数加载问题 -> 正文阅读

[开发测试]c++同名dll和dll中同名函数加载问题

1.前人工作

最近帮公司做一些软开方面的事,主要负责将项目环境进行统一配置,其中就涉及到了dll加载时如果遇到同名dll的解决方案,在网上寻找有效的解决方案,发现有价值的较少,找到可能有价值的链接如下:

(1)https://blog.csdn.net/mincheat/article/details/51312173

这个博主,对加载同名dll进行了测试,并提出了一些解决方案,最终给出的解决方案时通过进程间通信,这种方案从理论上来讲是没有问题的,但比较麻烦。

(2)http://cn.voidcc.com/question/p-ksrbkxaa-zr.html

解决方案不太明确

(3)https://www.shuzhiduo.com/A/1O5EvNB3d7/

这种方法也是主要使用了多进程的方法

(4)https://zhuanlan.zhihu.com/p/384716017

题主遇到的问题是,程序加载了同名但非程序所需的dll,通过设置dll搜索路径,题主解决了这个问题。

(5)https://bbs.csdn.net/topics/300015078

该链接给出了不少有用的思路,我目前使用的方法也是通过这个问答找到了一些思路

(6)http://blog.sina.com.cn/s/blog_53061af00102v19j.html

对非根目录下的dll调用以及依赖项给出了一些解决方案。

2.单进程同名dll加载

总结前人工作,可知对同名dll调用,使用多进程的方法是一种安全有效的方法,但是否有单进程的有效解决方案呢,答案是有的。

2.1需要知道的一些基本知识

(1)系统加载不同路径下的同名dll,是可行的,而且系统认为这是两个不同的dll,这是单进程可以加载两个同名dll的基础;

(2)dll加载有两种方式:动态加载和隐式加载;

(3)动态库加载的路径在程序中是可以设置的如SetDllDirectory

2.2独立的同名dll加载

在一个项目中main.exe原先加载其根目录(与exe目录相同)的a.dll完成工作,后续由于需要,需要加载一个A2文件夹的a.dll,此时,只需要将A2文件夹中的a.dll采用动态加载加载的方式调用,即可解决同名dll加载的问题,这是一种简单的场景。

2.3非独立的同名dll加载

如果在一个项目中main.exe原先加载其根目录(与exe目录相同)的a.dll完成工作,后续由于项目需要,要加载一个A2文件夹的b.dll,但b.dll依赖另外一个a.dll,此时的问题比较复杂,与b.dll依赖a.dll是动态加载还是隐式加载有关。

(1)根目录下的a.dll采用隐式先加载,如果b.dll动态加载的a.dll,那么只需要在main.exe中继续采用动态加载的方式加载b.dll,即可实现所需功能,不打架。

(2)目录下的a.dll采用隐式先加载,如果b.dll隐式加载的a.dll,此时如果使用b.dll的函数,那么起作用的是根目录下的a.dll,此时的解决方案是:将根目录下的a.dll和b.dll都采用动态加载的方式,使用哪个则加载哪个,用完卸载,在卸载b.dll时,a.dll也会被卸载,此时再加载根目录下的a.dll就会成功,这种方案在实际的项目环境中一般很难实行,这是因为,根目录下的a.dll一般被根目录下的其他dll使用,卸载了根目录下的a.dll在使用其他引用a.dll的dll时,会导致出错。根据查阅网上解决方案可能的解决思路如下:

在加载b.dll之前先将系统中的a.dll卸载,然后再加载b.dll,那么再完成b.dll的功能后,将其卸载,然后在系统中加载根目录下的a.dll。理论上这种方法可行,但这种方式没有试过。

3.dll名称不同,但导出函数相同

这种场景是,如果有两个dll,A.dll和B.dll,其中每个dll中都有一个PrintAB()的导出函数,这时,只要不把两个dll同时通过隐式加载到同一个exe,那么使用过程中是不会起冲突的。

4.其他做实验得出的一些结论

(1)如果进程中原先加载了一个A.dll,那么如果再次采用隐式加载另外一个版本的A.dll,那么一般会出现无法加载的情况,但如果使用动态加载,那么没有问题;

(2)如果动态加载b.dll,b.dll通过隐式引用a.dll,卸载b.dll时,会把a.dll也卸载;

5.结论

? ? ?综上,其实动态链接库中同名函数其实好解决,比较难解决的问题是同名dll,所以可以看到现在好多的dll库,如opencv,itk,vtk等库在发布dll时总是将版本号带上,这样可以避免由于版本不同导致的同名dll问题。

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-09-03 12:13:08  更:2021-09-03 12:13:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/17 23:36:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码