lib和dll的区别与使用

抛出几个概念:库、静态库、动态库、链接、静态链接、动态链接、显示链接、隐式链接。

         若不明白,请继续往下看。

 

什么是库

:库是写好的现有的、成熟的、可以复用的代码。库和可执行文件的区别是:库不是独立程序,它是向其他程序提供服务的代码。

有哪些库

有两种库:静态库(.a、.lib)和动态库(.so、.dll),它们是两种共享程序代码的方式。

静态库(Static library/Static link library):lib包含代码本身,在编译时直接将代码加入到程序当中。在可执行文件中包含了库代码的一份完整拷贝。vs编译成功后,只会生成一个.lib文件

动态库(Dynamic library/Dynamic link library):lib包含了函数所在的dll和dll中函数位置的入口信息。代码由运行时加载在进程空间中的dll提供。vs编译成功后,会生成两个文件.lib文件和.dll文件

 

静态库和动态库中的lib有什么区别

静态库中的lib:包含函数代码本身(包括函数的索引和实现),在编译时直接将代码加入程序当中。

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

所以:lib是编译时用到的,dll是运行时用到的。如果要完成代码的编译,只需要lib,如果要使动态链接的程序运行起来,只需要dll。

 

链接的方式

链接器将一个个目标文件(或许还有若干程序库)链接在一起生成一个完整的可执行文件。

静态链接:使用静态链接库,链接器从静态链接库lib获取所有被引用函数,并将库同代码一起放到可执行文件中。

动态链接:使用动态链接库,允许可执行模块(.dll文件或者.exe文件)仅包含在运行时定位dll函数的可执行代码所需的信息。

 

隐式链接与显式链接

隐式链接与显式链接是怎么回事呢?其实这两种链接方式只是dll的两种不同的加载方式而已。

隐式链接:1.Property->Linker->Input->Additional Dependencies中添加.lib文件,或者在源代码中加入指令#pragma comment(lib,"XX.lib")

                  2. Property->Linker->Input->Additional Library Directories中配置.lib文件所在的相对路径 

                  3. 将.dll文件置入工程所在目录,然后添加对应的.h头文件

显式链接:需要函数指针和WIN32 API函数:LoadLibrary、GetProcAddress装载,使用这种载入方式,不需要.lib文件和.h头文件,只需要.dll文件即可(将.dll文件放到工程目录中)。

 

写一个静态库以及如何使用静态库:

1.新建Win32 Project工程,Application type选择Static library类型。新建的工程中有stdafx.h和cpp,在上一篇博文中已介绍。

2.这次就写一个支持加/减操作的lib,新增MyMath.h和MyMath.cpp。

 MyMath.h:
 1 #ifndef _MY_STATIC_LIB_H_
 2 #define _MY_STATIC_LIB_H_
 3 
 4 class MyMath
 5 {
 6 public:
 7     MyMath();
 8     ~MyMath();
 9 
10     int Add(int nNumA, int nNumb);
11     int Sub(int nNumA, int nNumb);
12 };
13 #endif // _MY_STATIC_LIB_H_
View Code

MyMath.cpp

 1 #include "stdafx.h"
 2 #include "MyMath.h"
 3 
 4 MyMath::MyMath()
 5 {
 6 }
 7 
 8 MyMath::~MyMath()
 9 {
10 }
11 
12 int MyMath::Add(int nNumA, int nNumb)
13 {
14     return nNumA + nNumb;
15 }
16 
17 int MyMath::Sub(int nNumA, int nNumb)
18 {
19     return nNumA - nNumb;
20 }
View Code

接下来就新建一个exe工程,我们就取名:UseLibraryTest,该工程需要以下配置:

1.属性C/C++->General->Additional Include Directories要配置MyMath.h文件所在的相对路径。

2.属性Linker->General->Additional Library Directories要配置MyMath.lib文件所在的相对路径。

3.属性Linker->Input->Additional Dependencies中添加MyMath.lib。这一步或者可以改为在使用该lib的工程cpp中添加:#pragma comment(lib, "MyMath.lib")

4.最后在使用的cpp中添加#include <MyMath.h>

 1 #include "stdafx.h"
 2 #include <MyMath.h>
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     MyMath  MyMath;
10     int     nNumA   = 10;
11     int     nNumB   = 10;
12     int     nResult = 0;
13     
14     nResult = MyMath.Add(nNumA, nNumB);
15     cout << nResult << endl;
16 
17     nResult = MyMath.Sub(nNumA, nNumB);
18     cout << nResult << endl;
19 
20     return 0;
21 }
View Code

 在第3步中,若改为用#pragma comment(lib, "MyMath.lib")的代码如下:

 1 #include "stdafx.h"
 2 #include <MyMath.h>
 3 #include <iostream>
 4 #pragma comment(lib, "Static Library.lib")
 5 
 6 using namespace std;
 7 
 8 int main()
 9 {
10     MyMath  MyMath;
11     int     nNumA   = 10;
12     int     nNumB   = 10;
13     int     nResult = 0;
14     
15     nResult = MyMath.Add(nNumA, nNumB);
16     cout << nResult << endl;
17 
18     nResult = MyMath.Sub(nNumA, nNumB);
19     cout << nResult << endl;
20 
21     return 0;
22 }
View Code

如果第1步没有设置,则编译时会报错:fatal error C1083: Cannot open include file: 'MyMath.h': No such file or directory

如果第2步没有设置,并且lib也没有在该工程目录的情况下,则链接时会报错:LINK : fatal error LNK1104: cannot open file 'Static Library.lib'

如果第3步没有设置,会报错:

1> UseLibraryTest.cpp
1>UseLibraryTest.obj : error LNK2019: unresolved external symbol "public: __thiscall MyMath::MyMath(void)" (??0MyMath@@QAE@XZ) referenced in function _main
1>UseLibraryTest.obj : error LNK2019: unresolved external symbol "public: __thiscall MyMath::~MyMath(void)" (??1MyMath@@QAE@XZ) referenced in function _main
1>UseLibraryTest.obj : error LNK2019: unresolved external symbol "public: int __thiscall MyMath::Add(int,int)" (?Add@MyMath@@QAEHHH@Z) referenced in function _main
1>UseLibraryTest.obj : error LNK2019: unresolved external symbol "public: int __thiscall MyMath::Sub(int,int)" (?Sub@MyMath@@QAEHHH@Z) referenced in function _main

如果第4步没有做,会报错:error C2065: 'MyMath' : undeclared identifier等

我举出这么多报错的情况,只是为了让你能够熟悉这些错误。如果有一天有这样的报错,就能够快速的定位。。多看看报错信息也是很重要的,以提高解决bug的能力。

写一个动态库以及如何使用动态库:

1.新建Win32 Project工程,Application type选择dll类型。新建的工程里面会发现比静态库多一个dllmain.cpp。
2.同以上静态库一样,写一个支持加、减操作的dll。新增MyMath.h和MyMath.cpp。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/LuckyAnnika/p/5008511.html