windows动态链接库[DLL]与Linux共享库[SO]技术浅析

 

一、动态链接库的技术优点:

  1)节省内存和磁盘空间;因为动态库在内存或磁盘中只需一份,便可供多个进程或程序使用。

  2)模块化编程,方便协作;这一点静态库也能胜任。

  3)使用动态加载DLL或SO时,便于模块升级,无需重新编译或链接整个程序。

 

二、windows的动态链接库:

  1.windows的静态库生成的是.lib文件,其中包含了函数和数据实体,链接时合到程序中;

  2.windows的动态库生成.dll文件并导出一个.lib文件,该.lib文件中的函数没有实体[不是一个 准确的说法],函数内部是一个跳转,指向.dll中的函数实体;当然,在.lib中的跳转地址是一个相对地址[函数在dll的偏移地址];而且.dll文件是一个地址可重定位文件。

  3.动态库的使用有两种方法:

    1)动态链接:

      链接时将动态库导出的.lib文件链接到可执行文件中去。

      当程序加载到内存时,会有动态链接器将要加载的动态库加载到内存[已在内存则不用加载],此时该.dll内存地址确定,动态链接器将程序中的.lib部分中函数跳转地址改为原来的偏移地址加上该.dll起始地址的结果。这样就可以找到要调用的函数位置了。

      至于多进程共享一个动态库,每次动态连接器都将内存中的同一个库的地址映射到不同的进程空间[虚拟内存];并且映射到不同进程空间的地址很可能是不同的。

    2)动态加载:

      即在程序运行的过程中及时的将需要的库加载进内存[已存在则不用加载],通过相应的API拿到需要使用的动态库函数接口地址,使用函数指针的方式去使用,在使用完后可以动态的卸载动态库。

 

    (*)两种方式对比:

      (1) 第一种方法需要函数、变量的声明[即C/C++中要头文件],并且使用.lib来"欺骗"静态链接器;而第二种方法没有函数声明,使用函数时是采取函数指针的方式,所以静态链接器也没办法"找茬"。

      (2) 第一种方法由系统来维护动态库加载和卸载;第二种则需要程序员自行解决。那么同时第一种方法该动态库在该进程空间的生命周期与程序生命周期相同;第二种则由程序员决定。

      (3) 第一种在发布新的dll时,要用相应的lib文件重新链接程序;第二种则不需要,只需替换掉旧的dll.

 

三、Linux的共享库: 

  Linux的共享库与windows的动态库本质相同,特别是在动态加载时。差异主要体现在Linux的共享库产生.so文件时不会同时导出一个类似.lib的文件

  如果要用动态链接的方法,则需要将.so文件拿来链接时使用,不过它不会真的将该文件链接进最终的可执行文件。它只是记录下依赖该.so文件,并将引用于该.so的函数等符号记录到需要重定位的符号列表中[列表中包含了各个函数的相对地址],在程序加载到内存空间时,类似windows中,也是将确定的.so首地址与函数相对地址的和用来替换在程序中函数调用的地址指针[程序编译链接后,函数调用处均为地址跳转]。

 

posted @ 2022-02-09 14:29  威武的大萝卜  阅读(839)  评论(0编辑  收藏  举报