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。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM