静态链接、动态链接


静态库和动态库分别应用在静态链接方式和动态链接方式中,所谓静态链接方式是指在程序执行之前完成所有的链接工作,把静态库一起打包合入,生成一个可执行的目标文件(EXE文件)。所谓动态链接方式是指可执行目标文件在执行过程中才去加载调用相关功能函数,即在需要时才按需调用,是动态使用的。

静态库、动态库、隐式链接和显示链接中操作对象都是库,那么什么是库?


库是已经提前写好的、现有的,可以复用的代码,本质上来说库是一种经过编译生成的可执行代码的二进制形式,可以被操作系统载入内存执行。库分为两种:静态库(.a、.lib)和动态库( .so、.dll)

静态库和动态库中的静态和动态是针对库链接入程序时不同的处理方式而言的,看一下程序从代码编译成可执行文件的步骤:

静态库


静态链接中对应静态库,在链接阶段,会将汇编生成的目标文件(.o文件)与引用到的静态库(.a、.lib)一起链接打包到可执行文件,所以静态看的格式必定跟汇编生成的.o文件格式相似。可以把静态库简单看成是一组目标文件(包括.o和.lib文件)的集合,这些文件一起经过打包后最终形成一个静态库文件。

静态库的特点:采用静态库的链接方式把静态库中的内容一起链接到可执行文件中,会导致可执行文件较大。但是程序编译好之后不再需要静态库了(因为已经完整复制了静态库中的内容链接到本体程序员中了),移植方便,但这也导致了使用静态库的程序的更新升级会比较麻烦,每次微小的改动都需要编译整个程序重新加载静态库,并在客户端重新安装整个程序。

动态库:


动态链接中对应的是动态库,动态库在程序编译时不会被链接到目标代码中,而是直到可执行文件被执行过程中才被(按需)加载调用。

不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享的拷贝就可以了,规避了空间浪费问题,动态库的这种链接方式解决了静态库内存空间浪费和对程序更新比较麻烦的问题,当程序需要升级更新时,只需要将需要改动升级的模块对应的动态库发送给客户端替换即可,避免了需要重新下载安装整个程序包的“不能忍”。

动态库的特点:程序对动态库的加载是在执行阶段,需要同可执行文件一起发布和存在。可以实现进程间的资源共享,并用使得程序的更新升级操作变得很简单。


dll文件

动态链接库(Dynamic Link Library,DLL)是Windows系统中实现函数库共享的一种方式,可以使进程调用不属于其可执行代码的函数,dll文件包含最少一个已被编译、链接并与使用它们的进程分开存储的函数。

使用动态链接库有助于共享数据和资源,多个应用程序可以同时访问内存中单个DLL副本内的函数;把完成不同功能的函数编译到不同的动态库中,可以更为方便的对系统指定的模块进行独立的维护,而不会影响到系统中其他功能模块的正常运行,有助于程序的模块式开发。

lib文件

lib库也是一种实现函数共享的方式,分为两种,一种是静态链接库(Static Library/Static link Library),另一种是动态链接库DLL的导入库(Import Library)。

lib分为两种,一种是静态库中的lib,一种是动态库中的lib 。

静态链接库中的lib:Lib里包含了代码本身,在编译的时候,直接将lib文件中的代码插入到调用程序中,在调用lib的程序中包含了一份完整的拷贝,一起参与最终程序的编译。用于生成静态链接库lib的程序在编译后,只会生成一个.lib文件,不会生成.dll文件。

动态链接库中的lib:Lib里包含了函数所在的dll和dll中函数入口信息,代码由运行时加载在进程空间中的dll提供,用于生成动态链接库DLL(或lib)的程序在编译后,会生成两个文件,一个是.lib文件,一个是.dll文件。

可以简单的概括为在静态库中的lib包含了函数代码本身,在编译时直接嵌入到调用程序中;

在动态库中的lib包含了函数所在的dll文件和文件中函数位置的索引,函数实现的代码由运行时加载到进程空间中的dll提供。所以可以说lib 是在编译时用到的,dll是在运行时用到的。

隐式链接

隐式链接和显式链接是dll文件的两种不同加载方式。加载dll文件就是将DLL文件映射到用户进程地址空间,就可以在程序执行的时候进行函数调用。

隐式链接需要通过lib文件和.h文件加载,lib文件包含了dll允许应用程序导出的所有函数的符号名和可选的标识号,但是并不含有具体的代码实现。隐式链接不需指明DLL文件的实际存储路径,不需关心DLL文件的实际装载,而是LIB文件作为DLL的替代文件被编译到应用程序中。链接器检测到应用程序调用了LIB文件中的某个函数时,就会在应用程序EXE文件中加入相关信息。该应用程序运行时,系统会查看这个文件的DLL信息,并将DLL文件映射到地址空间。

系统运行时会从本地查找dll文件,寻找路径的先后顺序是:

  • 1. EXE文件所在目录
  • 2. 当前程序工作目录
  • 3. 系统目录
  • 4. Windows目录
  • 5. 环境变量中所有目录

VC中隐式链接的方法如下:
  • 1.Property->Linker->Input->Additional Dependencies中添加.lib文件,或者在源代码中加入指令#pragma              comment(lib,"XX.lib")
  • 2. Property->Linker->Input->Additional Library Directories中配置.lib文件所在的相对路径
  • 3. 将.dll文件置入工程所在目录,然后添加对应的.h头文件,头文件中声明dll中函数的方式为:                         extern "C"_declspec(dllimport) int FunctionName(int a,int b);

显式链接

显示链接不需要用到lib库,在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,能够更加有效的使用内存,在编写大型程序时往往使用显示调用。

该方法使用Load Library或者AfxLoadLibrary对DLL进行动态加载;使用GetProcessAdress获得所调用函数的指针;使用完毕后以Free Library或者AfxFreeLibrary将DLL从地址空间中卸载。

静态库、动态库,dll文件、lib文件,隐式链接、显式链接浅见的更多相关文章

  1. VS2015——命令行下编译、静态库动态库制作以及断点调试

    c程序编译流程 程序的基本流程如图: 1. 预处理 预处理相当于根据预处理指令组装新的C/C++程序.经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的 ...

  2. C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

    目录 . 引言 . 交叉编译 . Cygwin简介 . 静态库编译及使用 . 动态库编译及使用 . MinGW简介 . CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件 ...

  3. linux静态与动态库创建及使用实例

    一,gcc基础语法: 基本语法结构:(由以下四部分组成) gcc -o 可执行文件名 依赖文件集(*.c/*.o) 依赖库文件及其头文件集(由-I或-L与-l指明) gcc 依赖文件集(*.c/*.o ...

  4. windows库的创建和使用:静态库+动态库

    windows库的创建和使用:静态库+动态库   一.静态库的创建和使用 1. 静态库创建 (1)首先创建projecttest,測试代码例如以下: 1) test.h void test_print ...

  5. MFC中的DLL、LIb文件的创建、使用

     动态链接库Dynamic-Linked Lib 的创建与使用 动态链接库(Dynamic Link Library 或者 Dynamic-link Library,缩写为 DLL),是微软公司在微软 ...

  6. Linux中创建和使用静态库&动态库

    库本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行 Linux下库的种类 linux下的库有两种:静态库和共享库(动态库). 二者的不同点在于代码被载入的时刻不同. 静态库的代码在 ...

  7. c++中.dll与.lib文件的生成与使用的详解

    两种库: • 包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library.• 包含函数代码本身,在编译时 ...

  8. windows 静态和动态库

    c++中共有两种库:1.动态链接库LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library.(这 ...

  9. C++开发新版本vs使用旧版本vs编译的静态库动态库

    关于vs潜在的升级问题概述 (Visual C++)查看官网的介绍:潜在的升级问题概述 (Visual C++).主要问题: 1. 如果使用 /GL(全程序优化)进行编译,则生成的对象文件只能使用生成 ...

  10. VS2013生成、使用dll,lib文件

    VS2013生成DLL文件 vs2013创建及使用DLL 一般来说项目偏爱生成dll动态库文件,因为可以解决静态库造成的空间浪费和更新困难问题,另外创建静态库时,我一般是建立空项目后,在项目配置类型中 ...

随机推荐

  1. HDU 1248 寒冰王座 完全背包

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1248 中文题,大意就不说了. 第一道完全背包题,跟着背包九讲做的. 和0-1背包的区别在于所不同的是每种 ...

  2. 经验总结56--mybatis返回主键

    使用mybatis框架时,有时候须要新插入的数据的主键是多少. 1.oracle 因为oracle是建的序列文件,获取ID值. <insert id="insert" par ...

  3. hadoop2.7全然分布式集群搭建以及任务測试

    要想深入的学习hadoop数据分析技术,首要的任务是必需要将hadoop集群环境搭建起来,本文主要讲述怎样搭建一套hadoop全然分布式集群环境. 环境配置:2台64位的redhat6.5 +  1台 ...

  4. Multi-Tenancy模式,基础服务大规模扩张的时候,是应该推进了。

    这不是技术介绍.这是我要推进的工作,记在这里.服务的对象太多,必须隔离为不同租户了.

  5. 忙里偷闲( ˇˍˇ )闲里偷学【C语言篇】——(7)结构体

    一.为什么需要结构体? 为了表示一些复杂的事物,而普通类型无法满足实际需求 二.什么叫结构体? 把一些基本类型组合在一起形成的一个新的复合数据类型叫做结构体. 三.如何定义一个结构体? 第一种方式: ...

  6. 前端调用百度API

    <!DOCTYPE html> <html> <head>         <meta charset="UTF-8">       ...

  7. [Ramda] Difference between R.converge and R.useWith

    So what is Point-free function. Take a look this example: const getUpdatedPerson = (person) => R. ...

  8. http协议头文件的控制信息(转)

    通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息.这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成.HTTP的头域包括通用头,请求头,响应 ...

  9. NOIP模拟 拆网线 - 贪心策略+dp

    题目大意: 给一颗n个节点的树,保留最少的边,使得每个连通块的大小都大于等于2,并且连通块的点数和等于k. 题目分析: 要想留下的边数最少,就要尽量多的选择单独的边,这里就要贪心:尽可能多的选择单独的 ...

  10. mysql 数据库 添加查询 修改 删除

    cmd 命令行模式操作数据库 添加查询 修改 删除 ( 表 字段 数据)   一 查看数据库.表.数据字段.数据 1 首先配置环境变量 进入mysql  或者通过一键集成工具 打开mysql命令行   ...