Windows靜態庫和動態庫的建立和使用

2021-06-18 00:35:24 字數 4437 閱讀 7583

靜態鏈結庫(static libary)

偶們用vs2005做乙個靜態鏈結庫先

開啟vs2005,新建à專案(staticcai)àwin32控制台應用程式

新建static_lib.h 和static_lib.cpp 兩個檔案,這兩個檔案的內容如下:

static_lib.h:

int add(int x,int y);

int substract(int x , int y);

static_lib.cpp:

#include "static_lib.h"

int add(int x,int y)

int substract(int x,int y)

然後編譯,生成解決方案,好,這樣不出意外會在debug資料夾(與staticcai並列)下生成乙個staticcai.lib檔案,好了,這個就是我們做好的靜態鏈結庫。下面,我們看看怎麼用這個靜態鏈結庫。我們再新建乙個win32控制台程式,新建main.cpp內容如下:

#include 

#include "static_lib.h"

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

using namespace std ;

int main()

並且將staticcai.lib和static_lib.h這兩個檔案拷貝到與main.cpp並列的資料夾下。然後,我們編譯,鏈結,執行程式,就會出結果了

#pragma comment(lib, "static.lib")這句和我們在 專案à屬性à聯結器à新增依賴項 的效果是一樣的。至此,怎麼做靜態鏈結庫以及怎麼用靜態鏈結庫就搞定了。現在,我們把剛剛拷貝過來的staticcai.lib給刪了,我們發現,程式照樣執行,但是不能再鏈結了。所以,我們得出這樣的結論:我們再鏈結的時候需要靜態鏈結庫,一旦鏈結成功,生成了可執行檔案,那麼,靜態鏈結庫就不再需要了。

其次,偶們說第二個:動態鏈結庫(dynamic link libary)

同樣,我們來做乙個動態鏈結庫,和上面的步驟一樣,先建工程,只有最後一步稍有不同

然後,新建dll.cpp檔案(這裡我們就不做.h檔案了),敲入一下內容:

#define  dll_api _declspec(dllexport)

#include 

using namespace std;

dll_api int add(int a,int b)   //實現兩個整數相加

dll_api int subtract(int a,int b)   //實現兩個整數相減

然後,我們編譯,生成解決方案,就會在debug資料夾下生成dllcai.dll和dllcai.lib。好,至此,動態鏈結庫就做好了,下面我們來看怎麼用,新建乙個win32控制台程式,新建main.cpp內容如下:

#include 

using namespace std ;

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

extern int add(int a,int b);

extern int subtract(int a,int b);

int main()

然後把dllcai.dll和dllcai.lib拷貝到與main.cpp並列的目錄下。接著,編譯,鏈結,執行,就會看到和上一次一樣的結果了。然後,我們把dllcai.lib給刪了,程式照樣執行,但是不能再鏈結了,接著,我們把dllcai.dll給刪了,程式可以再編譯,鏈結,但是執行的時候就黃了。所以,我們說:對於動態鏈結庫,鏈結的時候需要.lib檔案,執行的時候需要.dll檔案。 

至此,靜態鏈結庫和動態鏈結庫我們就說完了,我們做一下對比和補充:

1 、 兩個lib檔案

我們發現,無論是靜態鏈結庫還是動態鏈結庫,最後都有lib檔案,那麼兩者區別是什麼呢?其實,兩個是完全不一樣的東西。staticcai.lib的大小為4kb,dllcai.lib的大小為2kb,靜態庫對應的lib檔案叫靜態庫,動態庫對應的lib檔案叫導入庫。實際上靜態庫本身就包含了實際執行**、符號表等等,而對於導入庫而言,其實際的執行**位於動態庫中,導入庫只包含了位址符號表等,確保程式找到對應函式的一些基本位址資訊。

2 、 對於靜態鏈結庫,我們在編譯和鏈結的時候已經將所有的**都匯入進來,因此,當生成可執行檔案以後,可執行檔案包含所有的**。因此,在可執行檔案執行時就不再需要靜態庫了,這也是為什麼我們刪掉staticcai.lib程式照樣執行;而對於動態鏈結庫,實際上,可執行檔案不包含dll中的內容,只是通過導入庫(.lib)知道了相應的位址資訊,因此,可執行檔案在執行時動態得去載入dll,這也是為什麼我們刪掉dllcai.dll後程式就不能執行了。

3 、 對於dll,我們是可以不要lib檔案的。

如果不要lib檔案,我們可以通過函式指標的使用達到我們的目的:

#define  dll_api _declspec(dllexport)

#include 

using namespace std;   //注意這裡的extern "c" , 這裡必須加

extern "c" dll_api int add(int a,int b)   //實現兩個整數相加

extern "c" dll_api int subtract(int a,int b)   //實現兩個整數相減

#include 

#include 

using namespace std ;

typedef int (*func)(int x , int y);  //函式指標

int main()

func add = (func)getprocaddress(hinstance, "add");

func sub = (func)getprocaddress(hinstance, "subtract");

cout << (*add)(3,4) << endl ;

cout << (*sub)(5,3) << endl ; }

顯然,這種方法沒有用lib檔案方便,如果為了每次呼叫乙個函式還要自己再弄乙個函式指標,多麻煩啊,所以,我們在實際開發中,用的眾多的第三方擴充套件庫,別人都是提供的:

.h  檔案(類,函式的宣告)

.dll 檔案(類或函式的實現)

.lib 檔案(導入庫)

小結:一、靜態庫

* 靜態庫是把程式執行時需要使用的函式編譯在乙個二進位制檔案中,擴充套件名為.lib。當程式link時把靜態庫中的二進位制資料和程式其它資料放到一起。程式運 行時不在需要lib和dll檔案的支援。這樣做的壞處是開發出來的程式占用磁碟空間較大。特別是windows系統中本來就有或很多程式執行都需要的函式 完全沒有必要每次開發程式時都要使用各自的靜態庫。

* 靜態庫為.lib檔案形式存在

* 鏈結後產生的可執行檔案包含了所有需要呼叫的函式的**,因此占用磁碟空間較大

* 如果有多個(呼叫相同庫函式的)程序在記憶體中間時執行,記憶體中就存有多份相同的庫函式**,因此占用記憶體空間較多。

二、動態庫

* 動態庫在開發時僅是把dll中的函式名和引數放到應用程式中,應用程式執行時根據函式名和引數呼叫dll中的函式來執行,這樣作業系統中的應用程式可以同 時使用同乙個dll。可以有效地節省硬碟空間,當然這樣做使得程式設計更有層次。也有利於軟體工程師的分工和資訊保安

* 動態庫以.dl檔案形式存在,且一般都有乙個對應的引入庫以.lib檔案形式存在。純資源dll不生成.lib引入庫。

>引入庫和靜態庫的副檔名均為*.lib,但是引入庫僅包含一些函式名和引數資訊,沒有函式體,是為呼叫動態庫服務的,它和動態庫的關係相當於.h檔案和.cpp檔案之間的關係;

* 動態庫兩種繫結方式

>靜態繫結(static blnding) 使用靜態繫結的程式在一開始載入記憶體的時候,引導程式就會把程式所有呼叫到的動態**的位址算出、確定下來。這種方式使程式剛執行時的初始化時間較長,不過一但完成動態裝載,程式的執行速度就很快。

2動態繫結(dynamic binding)   使用這種方式的程式並不在一開始就完成動態鏈結,而是直到真正呼叫動態庫**時,引導程式才計算(被呼叫的那部分)動態**的邏輯位址,然後等到某個時 候,程式又需要呼叫另外某塊動態**時,引導程式才又去計算這部分**的邏輯位址。所以,這種方式侄程式初始化時間較短,但執行期間的效能比不上靜態繫結 的程式。

* 使用動態庫的兩種方法(windows)

>方法一: load-time dynamic linking 

在要呼叫dll的應用程式鏈結時,將dll的輸入庫檔案(import library,.lib檔案)包含進去。具體的做 法是在原始檔開頭加一句#include ,然後就可以在原始檔中呼叫dlldemo.dll中的輸出檔案了。

>方法二: run-time dynamic linking 

不必在鏈結時包含輸入庫檔案,而是在源程式中使用loadlibrary或loadlibraryex動態的載入dll。

WINDOWS靜態庫與動態庫

編譯靜態庫時,只會產生.lib檔案。所有資料都在lib檔案中。靜態庫的使用方式只有一種,即靜態載入,在程式編譯鏈結階段,會將靜態庫中的所有資料都鏈結合併到最終生成的exe檔案中,鏈結完成後就不再需要靜態庫檔案,這樣方便程式移植,但是也帶來程式臃腫過大的弊端。同時,如果靜態庫中函式有所變化,需要重新編...

Windows系統下靜態庫和動態庫的生成方法

靜態庫的生成方法 直接建立靜態庫專案,寫好功能後,編譯生成即可,把頭檔案和靜態庫提供給別人即可使用 動態庫的生成方法 建立動態庫專案,在標頭檔案中寫入 ifdef dllexport define dll declspec dllexport else define dll declspec dll...

Windows靜態庫和動態庫區別

個人建議 能使用靜態庫的就不要使用動態庫,能使用隱式呼叫的就不要用顯示呼叫。注意 1 動態庫中的.lib檔案叫做導入庫,對於導入庫而言,其實際的執行 位於動態庫中,導入庫只包含了位址符號表等,確保程式找到對應函式的一些基本位址資訊。靜態庫中的.lib叫做靜態庫,本身就包含了實際執行 符號表等等 2 ...