不止Linux下关于共享库存在版本兼容性困扰问题,Windows下DLL共享库的使用问题更甚。很多Windows的应用程序在发布release版本时会一次性将所有用到的DLL一起打包形成一个大的安装包,用户只需一键安装,无需关注具体的DLL文件的配置问题。但也正是这种黑盒操作导致了可能存在某次安装,将系统中的新版本DLL文件被旧版本DLL给覆盖掉,虽然安装的程序可以运行了,但是其他程序可能出现问题了(最为常见的便是Visual studio C++的一些插件库版本覆盖问题)。

前人总结的经验,DLL HELL发生的三种主要场景:
1. 使用旧版本的DLL替代了当前系统的新版本DLL,导致了其他程序无法正常运行;
2. 新版本DLL引入覆盖了旧版本DLL,因为新版本的DLL设计缺陷,没有做到完全的向后兼容;
3. 新版本DLL本身就存在bug,导致程序运行崩溃,很少见。

解决DLL Hell的方法

预防DLL Hell的方法有以下几种:
1.静态链接(static linking):发布终极融合版本执行文件,从根本上杜绝了动态加载DLL的可能性,但也丧失了灵活升级的好处;

2.防止DLL覆盖
在Windows中,DLL的覆盖问题可以使用Windows文件保护(Windows File Protection WFP)技术来缓解。该技术从Windows2000开始使用。它能阻止未经授权的应用程序覆盖系统的DLL。第三方应用程序不能覆盖操作系统DLL文件,除非它们的安装程序捆绑了Windows更新包,或者在它们的安装程序运行时禁止WFP服务(当然这是一个非常危险的事);

3.避免DLL冲突(conflicting DLLs)
解决不同应用程序依赖相同DLL不同版本的问题的一个方案是,让每个应用程序拥有一份自己依赖的DLL,并且把问题DLL的不同版本放到该应用程序的文件夹中,而不是系统DLL目录中,当应用程序需要安装DLL时候,首先从自己的文件夹下寻找所需要的DLL,然后再到系统文件夹中寻找。

4. .NET下DLL Hell的解决方案
在.NET框架中,一个程序集(Assembly)有两种类型:应用程序程序.exe和库程序.dll。一个程序集包括一个或多个文件,所以需要一个清单文件来描述程序集清单,这个清单文件叫做manifest文件。
Manifest文件描述了程序集的名字、版本号、本地文件资源以及程序集依赖的各种资源。Manifest是一个XML描述文件,每个DLL有自己的manifest,每个程序也有自己的manifest。对于应用程序而言,manifest可以和可执行文件在同一个目录下,也可以作为一个资源嵌入到可执行文件的内部(Embed Manifest)。

在XP之后,操作系统在执行可执行文件时会首先读取程序集的manifest文件,获得该可执行文件所需要的DLL列表,再根据具体的DLL名(包括了版本号等信息)去寻找相应的DLL文件。但是这意味Windows得保存一个DLL共享库的所有版本,已提供给系统精准的匹配。(参见\Winodws\WinSxS目录,该目录下有一系列的同名DLL不同版本的保存)

对于每个版本DLL,它在WinSxS目录下都有独立的目录,这个目录命令规则要包含机器类型、DLL名字、公钥和版本号,这样多个不同版本的foo.dll就可以存在系统中而不冲突。但是这种方式过于死板,要求DLL版本等信息必须准确对应,所以这也是为什么Windows下的应用程序发布得自己配备所需的DLL的原因,因为很可能主机上没有你要的那个DLL版本。从这里一对比便可以看到,Linux的共享库版本符号机制便是一个好的设计。

Windows下动态链接之三:DLL Hell !相关推荐

  1. Windows下动态链接之二:DLL优化加速

    1. Windows动态链接下的导入函数的调用过程 在ELF结构下,函数调用因为 有全局符号介入的可能,所以除非用static关键词修饰,否则只要是函数调用,无论是否是模块内还是模块外,都需要经过.g ...

  2. Windows 下的 7 种 DLL 劫持技术

    本文讲的是Windows 下的 7 种 DLL 劫持技术,在本文中,我将列出半打可以在Windows运行用户模式的进程中使用DLL注入技术.也许可能会有更多类似的技术,但我正在和你分享的是我所拥有的第 ...

  3. mysql实现程序的动态链接_程序的链接和装入及Linux下动态链接的实现

    链接器和装入器的基本工作原理 一个程序要想在内存中运行,除了编译之外还要经过链接和装入这两个步骤.从程序员的角度来看,引入这两个步骤带来的好处就是可以直接在程序中使用printf和errno这种有意义 ...

  4. Windows 下创建目录链接 映射文件的方式不想改变路径直接使用映射路径的方式

    Windows 下创建目录链接 发表于 2019-10-27 | 分类于 后端 | 没有评论 在 Windows 下如果通过右键菜单->创建快捷方式生成的文件或文件夹,其实是生成了一个后辍为.l ...

  5. Windows下动态内存分配方式http://whx.tzgt.gov.cn/newOperate/html/7/71/711/3938.html

    这里的"动态内存"包含以下两个方面的内容:   1.内存.这里的"内存"指的是进程的虚拟内存空间.在Win32环境下,每一个进程拥有独立的,大小为4G(0x00 ...

  6. Windows下动态加载可执行代码原理简述

    xiaotie同学比较蛋疼,问C#里面能不能动态加载SIMD的汇编代码.C#我不知道,反正c/c++下面这事情很好做.顺手花了几个小时写了个例子和这篇博客. 总的来说,windows下要动态加载bin ...

  7. Windows 下 JNI 调用动态链接库 dll

    1. Java调用本地代码常见的两种方案 JNI JNI(Java Native Interface),有过不同语言间通信开发经历的一般都知道,它允许java和其他语言代码(尤其是C/C++)进行交互 ...

  8. linux编写日志接口so,linux下动态链接问题(.so文件的编写与调用) .

    .o 就相当于windows里的obj文件 .a 是好多个.o合在一起,用于静态连接 .so 是shared object,用于动态连接的,和dll差不多 sotest.c #include int ...

  9. Windows下静态链接库的使用

     静态链接是指将一个或多个静态链接库(.lib文件)在Link时期和调用该库的程序一起形成exe文件.网上关于静态链接库的理论叙述多且详尽,我就不再造轮子了,此处仅说明一下具体的使用方法. 创建一 ...

最新文章

  1. 爬虫必备工具,掌握它就解决了一半的问题
  2. 网站基本维护躲不过这三点!
  3. oracle sql练习_数据分析之学习SQL
  4. static关键字总结
  5. Python3 不换行打印
  6. 上传图片即时显示图片
  7. 文本挖掘(part5)--文本信息的分布式表示
  8. 认知空间是什么意思_Number是“数”,one是“一”,那么number one什么意思?
  9. Turtlebot3调试必看——爬坑笔记
  10. 我当圣诞老人跳舞啦!
  11. ArcGIS for Android Runtime100 基本操作(四)——GPS定位
  12. 淘宝手淘搜索怎么做?大神导航,一个神奇的网站,从此开启大神之路!
  13. RTMP网页视频抓取
  14. H5调用摄像头实现视频拍摄及iOS兼容性问题
  15. 简要介绍随机森林原理
  16. 【R语言数据科学】(十三):有趣的概率学(下)
  17. 教你去掉 U盘写保护
  18. Android ijkplayer播放rtsp直播流
  19. Excel或者WPS 报insatlling Office Customization 路径找不到的问题
  20. 大自然背景的清晨闹铃.wav

热门文章

  1. php验证电话号码是否合法,js代码验证手机号码和电话号码是否合法_javascript技巧...
  2. 卡巴斯基网络威胁实时地图链接(装逼或学习)。
  3. 如何做目录——目录的生成?
  4. 人人都是产品经理系列一
  5. OCR银行卡辨识SDK
  6. python输入float_float是什么意思_在python中 float是什么意思?
  7. scrollTo详解
  8. l5-repository的使用
  9. 双十二电容笔哪个品牌好?十大电容笔知名品牌
  10. 2023开学季哪款电容笔值得买?高品质电容笔品牌推荐