windows中静态库lib和动态dll的区别及使用方法
1. 静态库lib和动态dll的区别
1.1 项目类型
VS在建Win32项目时,有以下选项:
windows应用程序
控制台应用程序
DLL
静态库
最后两个类型:DLL和静态库,这两种项目类型是不可以单独运行的,必须在Windows应用程序调用他们执行,是提供的库函数而已。
1.2 两种lib的区别:
(1)静态库(.lib)
函数和数据被编译进一个二进制文件(通常扩展名为.LIB)。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其他模块组合起来创建最终的可执行文件(.EXE文件)。当发布产品时,只需要发布这个可执行文件,并不需要发布被使用的静态库。
(2)动态库(.lib文件和.dll文件)
在使用动态库的时候,编译后往往提供两个文件:一个引入库(.lib)文件(也称“导入库文件”)和一个DLL(.dll)文件。当然到了后面会告诉你如果只提供一个DLL文件,使用显示连接的方式也可以调用,只是稍加麻烦而已。
虽然引入库的后缀名也是“lib”,但是,动态库的引入库文件和静态库文件有着本质的区别。对一个DLL文件来说,其引入库文件(.lib)包含该DLL导出的函数和变量的符号名,而.dll文件包含该DLL实际的函数和数据。在使用动态库的情况下,在编译链接可执行文件时,只需要链接该DLL的引入库文件,该DLL中的函数代码和数据并不可复制到可执行文件,直到可执行程序运行时,才去加载所需的DLL,将该DLL映射到进程的地址空间中,然后访问DLL中导出的函数。这时,在发布产品时,除了发布可执行文件以外,同时还需要发布该程序将要调用的动态链接库。
只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。如果DLL不在内存中,系统就将其加载到内存中。当链接Windows程序以产生一个可执行文件时,你必须链接由编程环境提供的专门的 “引入库(import library)”。这些引入库包含了动态链接库名称和所有Windows函数调用的引用信息。链接程序使用该信息在.EXE文件中构造一个表,当加载程序时,Windows使用它将调用转换为Windows函数。
引入库LIb和静态库Lib的区别:
引入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于引入库而言,其实际的执行代码位于动态库中,引入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。但是引入库文件的引入方式和静态库一样,要在链接路径上添加找到这些.lib的路径。
1.3 动态库(Lib和DLL)和静态库Lib的区别:
其实上面已经提到了区别,这里再总结一下:
(1)静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了,最终的可执行文件exe会比较大。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。
(2)静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接 库。静态链接库与静态链接库调用规则总体比较如下。
静态链接库运行之前就加载了,而且一直存在直到关闭程序,动态DLL实在运行时再加载,不用一直占内存,dll模块内部更改了,是要替换Dll即可,方便维护。优点明显,但是dll如果丢失或被误删,就无法运行了
2. 静态库lib和动态dll的使用
2. 1 动态dll的使用
动态链接库的使用需要库的开发者提供生成的.lib文件和.dll文件。或者只提供dll文件。使用时只能使用dll中导出的函数,未导出的函数只能在dll内部使用。Dll的调用有显示连接和隐式连接两种:隐式连接需要三个东西,分别是*.h头文件,lib库(动态的),DLL库;显示连接只需要.dll文件即可。
2.1.1 隐式连接
隐式链接需要三个东西,分别是*.h头文件,lib库(动态的),DLL库,而这里的lib库仅是编译的时候用,运行时候不用,运行时只用Dll
2.1.1.1 添加Lib
方法1: 通过设置工程配置来添加lib库.
A、添加工程的头文件目录:工程->属性->配置属性->c/c++->常规->附加包含目录:加上头文件存放目录。添加头文件参考2.2.1.2
B、添加文件引用的lib静态库路径:工程->属性->配置属性->链接器->常规->附加库目录:加上lib文件存放目录。
C 然后添加工程引用的lib文件名:工程->属性->配置属性->链接器->输入->附加依赖项:加上lib文件名。
这种方法比较繁琐,且不直观,而且还可能要争对debug版本和release版本作不同的配置,因为我们生成的两个版本的库可能放在不同的目录中的.
方法2: 使用编译语句:
#ifdef _DEBUG
#pragma comment(lib,"..\\debug\\LedCtrlBoard.lib")
#else
#pragma comment(lib,"..\\release\\LedCtrlBoard.lib")
#endif
1
2
3
4
5
这种方法直观,方便,且可以按如上直接区分出Debug版本和Release版本的不同目录.当然,通过宏,还可以区分更多版本.但是在指定目录时,不小心容易出错.
方法3: 直接添加库文件到工程中.
就像你添加.h和.cpp文件一样,把lib文件添加到工程文件列表中去.
VC中,切换到”解决方案视图”—>选中要添加lib的工程–>点击右键–>”添加”–>”现有项”–>选择lib文件–>确定.
这个方法适用于在我的工程的debug版本和Release版本中都使用同一个lib库文件时.这样就省去了你1方法配置环境的繁琐,也省去了方法2种语句的可能性错误发生.。
2.1.1.2添加头文件
在调用DLL中导出的函数之前要include对应的头文件,可以写绝对路径,也可以拷贝到工程调用源文件的同一目录下,也可以通过VS添加(include)头文件目录,VS中配置方法:
(1)VS项目->右击属性->配置属性->VC++目录->包含目录
(2)VS项目->右击属性->配置属性->C/C++->常规->附加包含目录
2.1.1.3 添加dll
一般将dll拷贝到运行时目录即可,与调用者exe文件在同一目录,当然有其他方法添加环境变量PATH,
(1)VS项目->右击属性->配置属性->VC++目录->可执行目录
(2)设定DLL目录的位置,具体方法为:项目右击->属性 -> 配置属性 -> 调试 ->工作目录,在这里设置dll的路径就可以了
注1:release版本和debug版本的区分,每种版本的设置都是独立的,要分别设置
注2:单纯添加lib目录的方法有以下几种方法
(1):把.lib文件放在当前使用它的工程目录下;(如:.exe所在目录,或者工程代码所在的目录)
(2):对某一个项目:项目”->“属性”->“配置属性”->“VC++目录”->“常规”->“附加库目录”
(3):在vs中,“项目”->“属性”->“配置属性”->“链接器”->“常规”->“附加库目录”
(4):放在开发环境IDE的lib库目录下,例如:“C:\Program Files\Microsoft Visual Studio 8\VC\lib”,这是vs2005的vc开发的lib库目录。
注:在VS属性中配置路径时可以用绝对路径,也可以用相对路径,其中./表示当前目录,而../表示上一级目录
上面仅仅对单个项目有效,我们配置过opencv库的都知道,有一种是全局配置lib和include头文件,对所有的项目有效,以Debug版为例,步骤如下:
(1) 点击“视图”→“其他窗口”→“属性管理器”
(2) 从左侧项目中打开“Debug| Win32”→“Microsoft.Cpp.Win32.user”
(3) 双击“Microsoft.Cpp.Win32.user”,在弹出的窗口,点击左侧VC++目录,编辑右侧的可执行文件目录、包含目录与库目录,分别添加对应的路径
(4) 附加依赖项,单击“链接器”→“输入”→“附加依赖项”,填入依赖项.lib后缀的文件名。
2.1.2 显示连接
隐式链接虽然实现较简单,但除了必须的.dll文件外还需要DLL的.h文件和.lib文件,在那些只提供.dll文件的场合就无法使用,而只能采用显式链接的方式。这种方式通过调用API函数来完成对DLL的加载与卸载,能更加有效地使用内存,在编写大型应用程序时往往采用此方式。这种方法编程具体实现步骤如下:
①使用Windows API函数Load Library或者MFC提供的AfxLoadLibrary将DLL模块映像到进程的内存空间,对DLL模块进行动态加载。
②使用GetProcAddress函数得到要调用DLL中的函数的指针。
③不用DLL时,用Free Library函数或者AfxFreeLibrary函数从进程的地址空间显式卸载DLL。
使用LoadLibrary显式链接,那么在函数的参数中可以指定DLL文件的完整路径;如果不指定路径,或者进行隐式链接,Windows将遵循下面的搜索顺序来定位搜索DLL:
包含EXE文件的目录
工程目录
Windows系统目录
Windows目录
列在Path环境变量中的一系列目录
2.2 静态库lib的使用
静态lib中,一个lib文件实际上是任意个obj文件的集合,obj文件是cpp文件编译生成的。静态库的.lib文件包含了链接库的所有信息(函数代码和接口信息)。所以我们在调用静态库.lib时,只需要包含头文件目录(../include. .h),以及附加库目录即可。因此,静态链接库的使用需要库的开发者提供生成库的.h头文件和.lib文件
在VC中新建一个static library类型的工程TestLib,加入test.cpp文件和test.h文件(头文件内包括函数声明),然后编译,就生成了TestLib.lib文件。
别的工程要使用这个lib方式:
(1)添加lib
方法1):直接用”项目右击”->”添加”–>”现有项”–>选择lib文件–>确定,通过这种方式将.lib加入工程
方法2):工程属性-> 配置属性->链接器->输入->附加依赖项中添加要使用的Lib库的名字;在工程属性-> 配置属性->链接器->输入->附加库目录中输入.lib文件所在路径(相对或绝对路径)
方法3):或者在源代码中加入指令#pragma comment(lib, “TestLib.lib”),也可以指定完整路径(绝对路径或相对路径)#pragma comment(lib, “..\Debug\TestLib.lib”)。可以通过宏#if defined(_DEBUG)来区分用release或debug版本的lib。另外这里如果不指定完整路径,也要像方法2一样添加附加库目录。
如果不在工程属性中添加附加lib库目录,也可以将静态里边库比如TestLib.lib拷贝到工程所在目录,或者拷贝到执行文件生成的目录,或者拷贝到系统Lib目录中。
(2). 添加头文件
加入相应的头文件test.h。#include “test.h”
include file path可以为绝对路径,也可以为相对于工程所在目录的相对路径,如果头文件比较多,可以在project>settings>c/c++>preprocessor的Additional include directories中填入你的头文件所在目录,编译时会自动在此目录查找头文件。
原文:https://blog.csdn.net/dxzysk/article/details/66477147
windows中静态库lib和动态dll的区别及使用方法的更多相关文章
- 静态库lib和动态库dll相关总结
1.静态链接库LIB和动态链接库DLL的区别 若采用静态链接库,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了.而动态动态链接库则不必被包含在最终 EXE 文件中,EXE 文件执行时可 ...
- 静态库lib、动态库dll基础
首先从hello world!开始 //main.cpp文件 void cpu(); int main() { put(); ; } 在main.cpp中定义了一个cpu():函数,但没有实现其功能, ...
- 查看静态库(.lib)和动态库(.dll)的导出函数的信息 error LNK2001: 无法解析的外部符号 _Delete
转自VC错误:http://www.vcerror.com/?p=1381 在window下查看动态库的导出函数可以用vs自带的Dependenc工具: 查看静态库的信息要用命令行来实现: 首先运行V ...
- C语言中静态库和动态库笔记
库 库,故名思议,是存放东西的地方,其中存放的东西可以被多个人公用. 程序中借用库的概念,描述将代码进行抽取,这种代码被大多数程序使用, 其过程具有一定的模块化.封装.抽象的特征. 按照库的使用方式, ...
- Windows下静态库与动态库的创建与使用
Windows下静态库与动态库的创建与使用 学习内容:本博客介绍了Windows下使用Visual C++ 6.0制作与使用静态库与动态库的方法. --------CONTENTS-------- 一 ...
- 使用动态链接为什么还需要静态库lib文件
在Windows上使用动态链接时,不光需要头文件 .dll文件 还需要一个.lib 文件. 不是动态链接吗?为什么还需要静态库.lib文件? 实际上,这个.lib文件并不是静态库,而是 导入库 文件, ...
- Windows的静态库与动态库
Windows的静态库与动态库 1.静态库 1.1 静态库特点 运行不存在 静态库源码被链接到调用程序中 目标程序的归档 1.2 C语言静态库 C静态库的创建 创建一个静态库项目. 添加库程序,源文件 ...
- 在Linux中创建静态库.a和动态库.so
转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用 ...
- iOS中静态库-.a文件生成和使用
最近在使用使用一个网上的Demo的时候. 出现另一令人烦恼的问题 . 就是它里面有嵌套的工程. 如下图所示. 工程里面还嵌套有一个工程. 真的是让人煞费苦心 …其实这个问题看起来并不是很难, 如果是一 ...
随机推荐
- IIS是怎么处理同时到来的多个请求的?
假设有一台服务器,它的IIS上部署有一个Web应用程序-S,可以通过浏览器或其他方式进行访问. 假设有A.B.C三台电脑同时访问网站S,IIS接收到3个HTTP请求,然后分别为三个请求 ...
- WINDOWS开发PHP7扩展
最近在做个项目,需要用到唯一ID的生成,原本在Java和Delphi中,做了一个生成20位字符串(160bit)形式的唯一ID的算法,但是对比GUID(128bit),除了看起来比他短之外,其他并无优 ...
- 服务器和客户端Socket单向通信例子
看了两天socket通信,也参考了网上其他人是怎么写的. 下面我把最简单的socket例程贴出来 server代码: public class Server { private static int ...
- git filter-branch应用
1.修改author和committer git filter-branch --commit-filter ' export GIT_AUTHOR_EMAIL=me@example.com; exp ...
- topK问题解法
topK问题的最佳解法是堆排,下面介绍用堆排来解决该问题. 堆排解决topK问题的思路,取出前K个数,最重要的就是要减少比较的次数,用堆排维护一个K大小的堆,比如一个小顶堆,则堆顶为堆中最小的值,将堆 ...
- css 文字垂直居中问题
CSS 文字垂直居中问题 问题:在 div 中文字居中问题: 当使用 line-height:100%%; 时,文字没有居中,如下: html: <div id="header_log ...
- Java EE 学习(9):IDEA + maven + spring 搭建 web(5)- 博客文章管理
转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) . 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) Jav ...
- VMWare VMNet 8 的配置使用
网上有很多讲解VMWare网络原理的文章,我在这里就不在赘述,有兴趣的朋友可以自己搜 本章主要介绍下我们使用VM最常用的两种网络模式,VMNet 0 和 VMNet 8 本文均为原创,如需转载请标明, ...
- python转exe2
转载自 xiake200704 最终编辑 xiake200704 一.简介 py2exe是一个将python脚本转换成windows上的可独立执行的可执行程序(*.exe)的工具,这样,你 ...
- C# asp.net 导出数据库二进制字段到excel
前台的话不多说,本次只详细说下后台导出数据库中的二进制字段,上传下次有时间再说,有比较急的可以留言我 之前在网上搜了关于下载导出二进制字段的资料,发现都不是我想要的,都只是把上传的文件放到服务器然后下 ...