目錄
正文 拋出幾個概念:庫、靜態(tài)庫、動態(tài)庫、鏈接、靜態(tài)鏈接、動態(tài)鏈接、顯示鏈接、隱式鏈接。 若不明白,請繼續(xù)往下看。 什么是庫庫:庫是寫好的現(xiàn)有的、成熟的、可以復(fù)用的代碼。庫和可執(zhí)行文件的區(qū)別是:庫不是獨(dú)立程序,它是向其他程序提供服務(wù)的代碼。 有哪些庫有兩種庫:靜態(tài)庫(.a、.lib)和動態(tài)庫(.so、.dll),它們是兩種共享程序代碼的方式。 靜態(tài)庫(Static library/Static link library):lib包含代碼本身,在編譯時直接將代碼加入到程序當(dāng)中。在可執(zhí)行文件中包含了庫代碼的一份完整拷貝。vs編譯成功后,只會生成一個.lib文件。 動態(tài)庫(Dynamic library/Dynamic link library):lib包含了函數(shù)所在的dll和dll中函數(shù)位置的入口信息。代碼由運(yùn)行時加載在進(jìn)程空間中的dll提供。vs編譯成功后,會生成兩個文件.lib文件和.dll文件。 靜態(tài)庫和動態(tài)庫中的lib有什么區(qū)別靜態(tài)庫中的lib:包含函數(shù)代碼本身(包括函數(shù)的索引和實(shí)現(xiàn)),在編譯時直接將代碼加入程序當(dāng)中。 動態(tài)庫中的lib:包含函數(shù)所在的dll文件和文件中函數(shù)位置的索引,函數(shù)實(shí)現(xiàn)的代碼由運(yùn)行時加載到進(jìn)程空間中的dll提供。 所以:lib是編譯時用到的,dll是運(yùn)行時用到的。如果要完成代碼的編譯,只需要lib,如果要使動態(tài)鏈接的程序運(yùn)行起來,只需要dll。 鏈接的方式鏈接器將一個個目標(biāo)文件(或許還有若干程序庫)鏈接在一起生成一個完整的可執(zhí)行文件。 靜態(tài)鏈接:使用靜態(tài)鏈接庫,鏈接器從靜態(tài)鏈接庫lib獲取所有被引用函數(shù),并將庫同代碼一起放到可執(zhí)行文件中。 動態(tài)鏈接:使用動態(tài)鏈接庫,允許可執(zhí)行模塊(.dll文件或者.exe文件)僅包含在運(yùn)行時定位dll函數(shù)的可執(zhí)行代碼所需的信息。 隱式鏈接與顯式鏈接隱式鏈接與顯式鏈接是怎么回事呢?其實(shí)這兩種鏈接方式只是dll的兩種不同的加載方式而已。 隱式鏈接:1.Property->Linker->Input->Additional Dependencies中添加.lib文件,或者在源代碼中加入指令#pragma comment(lib,"XX.lib") 2. Property->Linker->Input->Additional Library Directories中配置.lib文件所在的相對路徑 3. 將.dll文件置入工程所在目錄,然后添加對應(yīng)的.h頭文件 顯式鏈接:需要函數(shù)指針和WIN32 API函數(shù):LoadLibrary、GetProcAddress裝載,使用這種載入方式,不需要.lib文件和.h頭文件,只需要.dll文件即可(將.dll文件放到工程目錄中)。 寫一個靜態(tài)庫以及如何使用靜態(tài)庫:1.新建Win32 Project工程,Application type選擇Static library類型。新建的工程中有stdafx.h和cpp,在上一篇博文中已介紹。 2.這次就寫一個支持加/減操作的lib,新增MyMath.h和MyMath.cpp。 MyMath.h:
MyMath.cpp 接下來就新建一個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 } 在第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 } 如果第1步?jīng)]有設(shè)置,則編譯時會報(bào)錯:fatal error C1083: Cannot open include file: 'MyMath.h': No such file or directory 如果第2步?jīng)]有設(shè)置,并且lib也沒有在該工程目錄的情況下,則鏈接時會報(bào)錯:LINK : fatal error LNK1104: cannot open file 'Static Library.lib' 如果第3步?jīng)]有設(shè)置,會報(bào)錯: 1> UseLibraryTest.cpp 如果第4步?jīng)]有做,會報(bào)錯:error C2065: 'MyMath' : undeclared identifier等 我舉出這么多報(bào)錯的情況,只是為了讓你能夠熟悉這些錯誤。如果有一天有這樣的報(bào)錯,就能夠快速的定位。。多看看報(bào)錯信息也是很重要的,以提高解決bug的能力。
寫一個動態(tài)庫以及如何使用動態(tài)庫:1.新建Win32 Project工程,Application type選擇dll類型。新建的工程里面會發(fā)現(xiàn)比靜態(tài)庫多一個dllmain.cpp。
2.同以上靜態(tài)庫一樣,寫一個支持加、減操作的dll。新增MyMath.h和MyMath.cpp。
|
|