首页
社区
课程
招聘
[原创]DLL, lib静态、动态库
发表于: 2014-8-21 00:13 12076

[原创]DLL, lib静态、动态库

2014-8-21 00:13
12076

说一说静态库、静态链接;动态库、动态链接,大牛不要拍砖哟!

1、静态库,分成两类吧,
                 第一种、指包含输出函数声明、实现代码的*.lib;
                 第二种、包含函数声明、函数引用地址的*.lib;
     第一种静态库多出现在DOS操作系统时代,在使用这种静态库时会增加目标PE文件尺寸。
     在win32以后的NT类型操作系统上,使用第二种居多,这一种不会增加目标文件尺寸,不过运行的效率相对低些。
   
     针对第一种静态库,我的理解,使用这种库最终编译链接生成的PE会包含库中实现代码;
     针对第二种静态库,是与DLL一同生成,在被引用时使用,DLL的实现代码不会被链接至目标PE;


2、动态库DLL
     首先,我的理解,无论是动态链接还是静态链接,目标PE内都不会包含DLL导出函数的实现代码,只会包含函数在DLL中的相对地址。动态链接和静态链接的区别在于,动态链接是在PE运行后使用对应的API来初始化、加载、析构,一个是在编译时确定库函数地址。从效率上讲后者编译出来的PE在启动初期会比者低。

针对DLL的静态链接(或DLL隐式调用),我的解释:在编译时链接生成目标PE时需要提供导入库函数声明、地址,这种方式生成的PE文件依赖库中可以查看到对应的DLL;
针对DLL的动态链接(或DLL显式调用),我的解释:生成的目标PE文件依赖库中不包含对应的DLL信息,而只是在PE运行时使用相应的LoadLibrary, GetProcAddress, FreeLibrary来动态调用DLL中函数;


总结,静态库(文中第二种静态库)不一定会增加目标PE尺寸,而DLL一定不会增加目标PE尺寸。

增加目标PE尺寸定义:包含引用库函数实现代码。
注,红色部分,是我后期增加的。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 3
支持
分享
最新回复 (27)
雪    币: 23
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
动态库多了一步映射。我是这么理解的,其他都一样,其实动态库,就是时间换空间的思想,我感脚,以后随着内存的增加,会慢慢消失这种技术
2014-8-21 00:33
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3
动态库? 静态库呢?有时候出来的静态库,体积还是蛮大的,加到内存,不管内存多大,都不太可取哦
2014-8-21 09:07
0
雪    币: 293
活跃值: (287)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
动态库、静态库、静态编译、动态编译 还是有区别的哟

包含代码的.lib、.a等后缀文件才叫静态库,lib只是库的意思,没有任何文档说lib文件就是静态库。就像.com它并不一定是DOS 16位程序,很多win32程序也可能.com,比如mode.com, more.com。还觉得我说错的话,可以查查各种文档里面对静态库的定义
不管哪种 lib 都是不包含运行时地址信息的,DLL生成的lib文件只记录dll名称、函数名称。某些编译器静态编译还不需要lib文件,只要编译的时候指定dll、函数即可。

概念都没弄清,话题谈得根本没意义

注:红色部分,是我后期增加的
2014-8-21 09:19
0
雪    币: 7048
活跃值: (3527)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
5
出来的静态库很大。
1是可能因为你开启了链接依赖项。导致你的库会静态链接一些使用的第三方静态库。
2是可能是debug版。

但是不影响最终二进制文件。
在链接生成exe或dll时,并不是把整个lib链接进去的, 而是根据你的代码所使用的符号。链接lib中导出该符号的obj及obj的依赖项。

这些其实你可以在看msvc crt的代码就可以发现。一般一个编译单(*.c,*.cpp)都是有相关性的一些函数或者单独的函数。
2014-8-21 09:32
0
雪    币: 459
活跃值: (398)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
6
受教
2014-8-21 09:37
0
雪    币: 23
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
要是内存以后都能达到500G,估计连虚拟内存都会消失,而这种可能越来越近噢
2014-8-21 11:19
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
8
这种想法完全错误~  动态库的主要作用是把功能模块独立出来用于共享,提供公共接口,而不必关心具体实现~  一个库的功能不需要共享的话,你使用静态或动态方式都无所谓,但是需要共享的话,动态库就比较方便了~  而动态库呢,只要接口不变,它的具体实现有没有变化根本不需要关心,比如CreateFile这种系统dll中的API,从98时代到现在其内部实现不知道升级了多少版本了,但是参数定义一直没变化,使用这个API的程序也就不需要做什么变化就可以正常使用并且可以享受其内部实现的新特性~ 而使用静态库的话,相应的功能每升级一次,你想使用新功能就得重新编译一次程序,何必呢?



64K内存的时代,人们绞尽脑汁在想着如何节省每一字节的内存使用时肯定在想,如果内存能达到64M那该多好啊,就可以想用就用了~
而现在家用机的内存普遍达到了4G、8G左右,但是应用软件使用的内存也越来越大,总还是感觉不够用的~  至于服务器,呵呵,128G或者更大内存的服务器现在也多的是吧? 你问问数据库管理员内存够用吗? 所以,一个时代有一个时代的问题,要用发展的眼光来看~  少年,你想得太简单了~
2014-8-21 13:04
0
雪    币: 23
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
你不感觉现在的dll方案,每次升级都很浪费精力么?而且PE内的那个1字节,版本标识,我感脚,几乎没用,不如直接附到程序内部,节省开发精力,用大量的空间换取开发的时间不好么?ARM现在不也是这种思想么?
2014-8-21 13:20
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
10
纠正一下楼主的认识~~


这个说法是完全错误的,静态链接时就不存在DLL了,函数的实现代码被整合到EXE中了,如果有DLL,那肯定是动态链接,必然不包含函数的具体实现代码

举个例子:比如你要调用模块ModA的一个函数FuncA,如果链接之后,FunA的函数体也是在exe内部,那么就是静态链接,单独一个exe就可以运行;如果FunA的函数体在模块ModA.dll中,那么这就是动态链接,运行的时候需要加载ModA.dll。

事实上,不管是静态链接还是动态链接,都需要提供头文件(包含函数接口声明)和lib文件(动态链接也需要lib哦
只不过:
静态链接需要的lib,一般文件比较大,因为它包含了函数的具体实现,链接时会和exe的主体链接在一起,当然会增大文件尺寸,因为它里面有货啊
动态链接需要的lib,一般文件比较小,因为它只包含了函数的原型和地址(其实就是一个jmp [IAT]引用),它只不过会在exe的IAT里增加几项内容,几乎不影响文件大小

这两者现在用得都很多,看具体场景,与时代无关~
至于效率上,这两者没有区别,就比如吃饭一样,区别在于你是在自己家吃饭还是到邻居家吃饭,主要时间消耗在吃饭这个过程上,到自己家(EXE内部jmp)和到邻居家(jmp [IAT])的这个过程需要的时间完全可以忽略不计

关于测试:
楼主可以用VC建立一个mfc工程,分别用"使用共享MFC库"和“使用静态MFC库”,比较一下编译出来的文件的大小、导入表、运行效率就一清二楚了
2014-8-21 13:31
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
11
有没有用不是你感觉没用就没用~ 你所谓的空间换时间,就是把代码整体在EXE内部,增加了EXE的体积,来换那么一点点的时间? 我上面讲了,运行时间上没有差别,而你这样反而增加了许多不便~  真想提高效率,那就好好优化代码(自己的,或者是库的)
要不然你如何解释现在的绝大多数程序都是使用的动态链接方式呢? 我还从没听说过DLL这种模型会消亡
2014-8-21 13:34
0
雪    币: 807
活跃值: (2228)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
任何人写的程序,不管是采用静态链接还是动态链接,都不能脱离操作系统的底层支持,从这个意义上来说,不管什么平台上的程序,操作系统都是其中不可分割的一部分,而操作系统提供的功能几乎只能采用动态链接,其他别无选择。只有自己有源代码的子程序库,你才有机会决定是采用静态还是动态链接的方式进入你的程序,如果不涉及较为敏感的软件保护功能,作为一般的公用模块,采用动态链接无疑是最优选择。
2014-8-21 13:47
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
从程序使用dll的角度来看,更多的原因可能是为了功能模块化,或者开发的便利。主要原因绝大部分并不是为了省内存。
2014-8-21 13:50
0
雪    币: 23
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
你说的这个到点上,关键就是系统的支持这块问题上,我认为如果能把系统也独立出来看的话,以后就不存在进程这种小概念,而是VM的大概念就好做了。DLL的独立性不是关键问题,假设有一种技术类似VT的,可以把程序运行独立包裹起来,而凌架于系统之上的办法,就有点像现在的WIN2012的意思(2012这方面只是刚开始尝试)。那DLL这种东西就是可有可无。其他的问题,像程序里是静态库方便还是动态库方便,都是些无关紧要的问题。
2014-8-21 13:57
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
同意~
动态链接库,静态链接库

显式加载,隐式加载

楼主的一些讨论可能混淆了部分概念。
2014-8-21 16:17
0
雪    币: 50
活跃值: (44)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
请见原文后增加内容,红色字体部分。
2014-8-21 22:32
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
第一种静态库多出现在DOS操作系统时代,在使用这种静态库时会增加目标PE文件尺寸。


这句话是错的。 静态库任何时候都有。 现在也很多。只是你不知道而已。
2014-8-21 22:40
0
雪    币: 23
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
还纠结这问题呢?哈哈,静态库基本上就=.lib,咱们用的程序里必须有很多静态库
2014-8-21 22:43
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
19
针对楼主后来修改的内容:
你所说的第二种,根本就不叫静态库好不。。。。这叫正宗的动态链接



你这里所说的针对DLL的静态链接,跟上面你所谓的“第二种静态库”根本就是一回事,这个是正宗的动态链接
至于你所说的“针对DLL的动态链接”,这根本就不叫链接,因为从编译链接的角度讲你的程序没有跟目标DLL发生任何依赖关系,这种真正的叫法叫“动态调用”,可以针对任何DLL

归根到底,就两种,实现代码在lib中然后链接时被整合到exe中的叫静态链接,实现代码不在lib中链接后exe的导入表中包含了相关模块引用在使用时需加载dll的叫动态链接,哪有那么多分类
2014-8-21 23:33
0
雪    币: 42
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
楼主 理解有偏差,红色字包括在内
第二种静态库 根本不是那么回事
用汇编写个简单程序验证,就知道了
2014-8-22 08:33
0
雪    币: 50
活跃值: (44)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
已经修正原文中表述不准确内容。
2014-8-22 09:51
0
雪    币: 1157
活跃值: (847)
能力值: ( LV8,RANK:150 )
在线值:
发帖
回帖
粉丝
22
感觉你没搞懂 你的程序和操作系统的关系,

1. windows操作系统不可能开源
2. 程序员不能把精力花在如何点亮屏幕的某个像素这种问题上

所以这跟独立进程没有任何感念上的联系吧,岂是VT能解决的问题啊
2014-8-22 10:29
0
雪    币: 11037
活跃值: (17540)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
我来学习经验,支持楼主
2014-8-22 11:02
0
雪    币: 23
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
很不幸,我现在做的正是这方面工作。很坚苦。哎
2014-8-22 22:03
0
雪    币: 54
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
那么windows自己的dll,有没有提供def文件呢?

一般书本在讲解dll时候,都提到, 导出函数时候,需要提供def文件。

我的问题是:

windows自己就的 dll 有没有提供def文件?

第2:

请问为什么很多开发工具,比如 vc等工作, 都会带一些叫kernle32.lib 的文件。

操作系统已经提供了kerne32.dll和kernel32.lib了,

vc还提供干嘛?
2014-8-23 20:09
0
游客
登录 | 注册 方可回帖
返回
//