VS2013生成、使用dll,lib文件

一般来说项目偏爱生成dll文件,具体原因后面会解释。

什么是库

库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。

所谓静态、动态是指链接。回顾一下,将一个程序编译成可执行程序的步骤:

静态库

之所以称为【静态库】,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。

试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。静态库特点总结:

1. 静态库对函数库的链接是放在编译时期完成的。

2. 程序在运行时与函数库再无瓜葛,移植方便。

3. 浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。

Windows下创建与使用静态库

创建静态库(.lib)

创建win32控制台程序时,勾选静态库类型(下面的预编译等选项可选可不选);打开工程“属性面板”-”配置属性”-”常规”,配置类型选择静态库。

程序编译通过后,Build项目即可生成静态库。即可生成.lib,输出栏会显示出静态库的位置。

使用静态库

如果将静态链接库拷贝到工程目录下,则可以只进行这一步:“属性面板”-”配置属性”- “链接器”-”输入”,附加依赖库中输入静态库名StaticLibrary.lib。

如果没有进行拷贝,则需要将路径添加到工程中,“属性面板”-”配置属性”- “链接器”-”常规”,附加依赖库目录中输入,静态库所在目录;

注意:!!!当我们作为团队的一个模块,给其他人链接库的时候,除了.lib文件还要给对方头文件,否则别人将不知道如何调用。

动态库

通过上面的介绍发现静态库,容易使用和理解,也达到了代码复用的目的,那为什么还需要动态库呢?

为什么还需要动态库?

为什么需要动态库,其实也是静态库的特点导致。

1.空间浪费是静态库的一个问题。

 

 2.另一个问题是静态库对程序的更新、部署和发布页会带来麻烦。如果静态库liba.lib更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新

 

动态库特点总结:

1.动态库把对一些库函数的链接载入推迟到程序运行的时期。

2.可以实现进程之间的资源共享。(因此动态库也称为共享库)

3.将一些程序升级变得简单。

4.甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。

创建动态库(.dll)

我们使用vs2013来生成Dll,其实使用其他的版本也是同理如此。步骤如下:单击“新建项目”,选择“Win32 项目”,选择“下一步”,然后到了如下界面:

点击“DLL”,并同时点击“导出符号”。然后点击“完成”。

 

先看下面这段代码:

#ifdef MAKEDLL_EXPORTS
#define MAKEDLL_API __declspec(dllexport)
#else #define MAKEDLL_API __declspec(dllimport) #endif

如果定义了MAKEDLL_EXPORTS,然后我们再定义MAKEDLL_API为__declspec(dllexport),否则我们定义__declspec(dllimport)。前者主要为生成DLL的项目所使用,后者为使用DLL的项目所使用。dllexport 和 dllimport 存储类特性是 C 和 C++ 语言的 Microsoft 专用扩展。可以使用它们从 DLL 中导出或向其中导入函数、数据和对象。

值得说明的是:

为什么要导出符号呢?

这是因为“导出符号”,将为我们创建生成DLL的模板。仔细观察,vs自动为我们创建了导出变量nMakeDLL,导出函数fnMakeDLL,导出类CMakeDLL。如果上面没有点击“导出符号”,将不会生成这些。所以为了方便DLL的创建,我们最好还是使用“导出符号”。

接下来,你可以改写上面的类和函数,然后点击项目,选择“生成”即可产生DLL和LIB。为了简化起见,本例只考虑导出函数。

修改完成后点击Build项目,在输出栏显示dll文件的生成位置。

有的博客中会要求生成动态库需要设置工程属性,打开工程“属性面板”-”配置属性”-”常规”,配置类型选择动态库。但是现在的VS版本在建立项目选择dll的时候已经自动设置了。

生成的DLL文件如下图所示:

这里可能大家有个疑问,动态库怎么还有一个DynamicLibrary.lib文件?即无论是静态链接库还是动态链接库,最后都有lib文件,那么两者区别是什么呢?其实,两个是完全不一样的东西。

 

StaticLibrary.lib的大小为190KB,DynamicLibrary.lib的大小为3KB,静态库对应的lib文件叫静态库,动态库对应的lib文件叫【导入库】。实际上静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息

使用动态库

而在引用一个新的dll时,比如我们采用静态引用的方法时,我们一般需要dll的.h,.lib和.dll三个文件,这时我们在新建项目的“属性”中选择“C/C++”-》“常规”-》“附加包含目录”,添加.h的路径,在“链接器”—》“常规”-》“附加库目录”中添加.lib的路径,同时我们还需要添加.lib的附加依赖项,这时可在“链接器”—》“输入”—》“附加依赖项”,填写**.lib ,最后还需要加载dll的路径,此时有两种方法最为常见。第一种,我们先直接运行程序,这时会出现一个错误,说“缺少什么dll”,我们只需将此前生成的dll,放在debug或release目录下,即可编译通过。第二种方法,直接将dll放在与.cpp同一目录下,即可编译通过。或者你也可以放在某一个新建的bin文件下,然后在项目的“path”中填写.bin的路径,如下所示:

填写路径时注意,前面的"path=%path%;" 必须有,后面可填写绝对路径相对路径。

另外我们再仔细讲讲lib的使用。

使用lib库有两个方法,一个是直接把lib引到工程目录下,在需要用到的地方include一下就可以。代码是:

#pragma comment(lib, "testCpp.lib")

另外一个方法是直接设置库路径,就不用把lib引到工程目录下了。直接点开工程属性,在配置属性-》连接器-》常规-》附加库目录中添加库

vs2013生成lib4

 

vs2013生成lib5

 

之后确认。

在配置属性-》连接器-》输入-》附加依赖项。如图填写

vs2013生成lib6

 

之后确定,运行工程就可以了。

总结一下,我们使用别人的库时,如果想偷懒的话,将.h,.lib,.dll都放在工程目录下,最后会发现我们需要在使用dll的main函数中加载上头文件,再像第一种方法一样,链接lib,就可以直接使用了。可参考文件:testDLL.zip

但是我更推崇另一种方法,就是我们单独建立include,bin,lib文件夹,然后将他们分别按照上面的方法链接上。这样如果要添加的库比较多时,会更加整齐,可读。

总的来说;.h,.lib,.dll的添加方法其实各有很多种,其中.h有两种:

1. 直接放在工程目录下

2. 建立include文件夹,放在里面,然后在项目属性的“C/C++”-》“常规”-》“附加包含目录”,添加.h路径即可。

.lib的方法有两种

1.直接放在工程目录下

2.建立lib文件夹,放在里面,然后在项目属性的“链接器”-》“常规”-》“附加库目录”,添加.lib路径即可。

dll的方法有两种

1.直接放在工程目录下

2.建立bin文件夹,放在里面,然后在项目“环境”中添加bin的路径(PS:最好不要用这个)

.lib的附加依赖项有2种:

1.在“链接器”——》“输入”-》“附加依赖项”,填写lib名称

2.在main文件前面,添加语句:

 

#pragma comment(lib, "testCpp.lib")

以上皆可以自由组合。 

最简单的方法就是全部放进.cpp目录下,然后将.lib文件加入链接器-输入-附加依赖项就可以了。如果觉得有点乱,可以把.h文件和.lib文件拿出来放进文件夹,然后按照上面的方法进行设置。



转载: https://www.cnblogs.com/qinguoyi/p/7257353.html

猜你喜欢

转载自blog.csdn.net/lihaidong1991/article/details/79458076
今日推荐