静态链接、动态链接


静态库和动态库分别应用在静态链接方式和动态链接方式中,所谓静态链接方式是指在程序执行之前完成所有的链接工作,把静态库一起打包合入,生成一个可执行的目标文件(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. 5DXTPlayer串口调试小结

    小结 过程总是艰难. 首先是没有准备好. 没有安装vs2012,安装的时候,出现各种状况,因为先安装的2013高版本,造成12安装不正确,程序编译出问题.没有办法,只好卸载vs2012,2013及其各 ...

  2. Auto Layout深入理解,及masonry简单介绍

    本篇博客是本人在学习自己主动布局过程中对自己主动布局的理解和整理,分三部分介绍,内容可能会有所反复.见谅. 一.autosizing与Auto Layout对照,及Auto Layout简单介绍 1. ...

  3. Swift3.0 功能二 (表情键盘与图文混排)

    随着iOS越来越多表情键盘以及图文混排的需求,本文运用Swift3.0系统的实现其功能以及封装调用方法,写的不好,如有错误望各位提出宝贵意见,多谢 项目源码地址: 相关知识点都有标识 项目源码地址 废 ...

  4. WCF走你~异常篇(永久更新...)

    下面是我个人在进行WCF开发时,遇到的问题及相关的解决方法,供大家一起学习 1. ......HTTP 响应时发生错误.这可能是由于服务终结点绑定未使用 HTTP 协议造成的. 解决:把返回的实体类添 ...

  5. js javascript正则

    var re = new RegExp("^[0-9]$"); 或者 var re2 = /^\d$/;//这个好像兼容性更好,比如你在上面的语句里面写\d,就总是返回false, ...

  6. [React] Update Component State in React With Ramda Lenses

    In this lesson, we'll refactor a React component to use Ramda lenses to update our component state. ...

  7. [Most.js] Create Streams From Single Values With Most.js

    Most provides many means for creating streams, the simplest of which is the offunction. In this less ...

  8. PHP移动互联网开发笔记(3)——运算符与流程控制

    一.PHP的运算符 PHP中有丰富的运算符集,它们中大部分直接来自于C语言.按照不同功能区分,运算符可以分为:算术运算符.字符串运算符.赋值运算符.位运算符.条件运算符,以及逻辑运算符等.当各种运算符 ...

  9. 数据结构与算法——常用数据结构及其Java实现

    前言 仿佛一下子,2017年就快过去一半了,研一马上就要成为过去式了,我打算抓住研一的尾巴,好好梳理一下数据结构与算法,毕竟这些基础知识是很重要的嘛.所以准备在这里搞一个系列的文章,以期透彻. 本系列 ...

  10. 具体分析contrex-A9的汇编代码__switch_to(进程切换)

    //函数原型:版本号linux-3.0.8 struct task_struct *__switch_to(structtask_struct *, struct thread_info *, str ...