動態連結庫與靜態連結庫

裁決者發表於2021-11-19

程式碼分發方式

image

動態庫與靜態庫唯一的區別就是動態庫多了個dll檔案

庫的作用

  • 程式碼解耦、重用
  • 對外提供服務(export)
  • 典型應用:exe呼叫dll。我們開啟軟體目錄一堆dll,少量exe就是這個道理

對於小軟體,它會把程式碼都寫到exe裡面,但是大軟體程式碼是需要重用的。

以火絨安全為例:

image

庫的分類(形式)

  • 靜態庫:與exe打包成exe(一個檔案),windows就是.lib檔案
    linux就是.a檔案
    它們在呼叫時會與它們的呼叫者.exe打包成一個.exe
    【其實windows會變成pe可執行檔案,linux是.elf可執行檔案,這裡為了方便理解這麼說】

  • 動態連結庫(共享庫)
    與exe是獨立的2個檔案
    windows就是.dll檔案
    linux就是.so檔案

動態庫就是當你呼叫dll檔案的時候,別人也可以呼叫,也就是說是可以重用的,而靜態庫是不可以的。

靜態庫與動態庫的區別

  • 靜態庫
    1、優點:程式碼合併到模組中,無零散檔案。
    2、缺點:模組體積變大,當多個模組使用該庫時,記憶體中有多份程式碼。

image

  • 動態庫
    1、優點:模組體積幾乎不變,當多個模組使用該庫時,記憶體中只存在一份程式碼。
    2、缺點:程式碼在單獨檔案中,有零散檔案。

image

總結:
    靜態庫的程式碼有改動時,所有依賴它的檔案都要重新編譯。動態庫不用(某些更改),可以只更新動態庫檔案(.dll檔案)。

C/C++到可執行程式的過程

image

靜態庫配置方法

image

首先我們編譯好了一份靜態庫檔案,只有.h檔案和.lib檔案

image

lib檔案使用方式有兩種,第一種是最簡單的,一般自己做練習的時候使用比較好,但是如果這樣配置庫的話並不會很方便,它會使你的程式碼顯得雜亂。

第一種:

通過程式碼#include ".h檔案絕對路徑",然後通過#pragma comment(lib,"lib檔案絕對路徑")來引用lib檔案

StabicLib.h程式碼:(返回兩個數之和)

#pragma once
int Add(int a,int b)

主程式程式碼:

#include <windows.h>
#include <iostream>
#include ".h檔案絕對路徑"
#pragma comment(lib,"lib檔案絕對路徑")

using namespace std;

int main()
{
    cout << Add(1,1) << endl;
    return 0;
}

執行結果:(返回值2)

image

第二種:【推薦】

我們點選專案->屬性,然後步驟如下

image

我們在這裡寫下標頭檔案的目錄(只需寫到資料夾路徑,不需寫到檔案路徑)

image

然後標頭檔案就配置好了

接下來是lib檔案,lib檔案是給連結器看的,我們需要配置它的目錄

image

同理,在這裡填上lib資料夾路徑

image

然後還需要在輸入->附加依賴項中寫上lib檔案的名字

image

這樣就配置好了,但是需要注意這裡的配置是要和專案配合使用的
Debug配Debug,X86配Win32

然後接下來我們就可以像正常使用別的庫一樣,使用它

程式碼:

#include <windows.h>
#include <iostream>
#include <StaticLib.h>

using namespace std;

int main()
{
    cout << Add(1,1) << endl;
    return 0;
}

然後就可以正常執行了

image

動態庫配置方法

image

主體流程基本差不多,只是多了個dll檔案的配置

可以看到這裡有三個檔案

image

.h檔案和.lib檔案與靜態相同這裡就不再演示【Dll.dll檔案我們不需要配置】

我們需要注意要把dll檔案複製到專案編譯後的專案資料夾裡

image

程式碼:

#include <windows.h>
#include <iostream>
#include <Dll.h>

using namespace std;

int main()
{
    cout << Add(1,1) << endl;
    return 0;
}

執行:

image

注意:
    動態庫的特點是需要dll檔案與exe檔案在一起或者是在一些特定的dll搜尋路徑下即可。

衍生技術

黑客hook dll:程式碼替換或叫程式碼劫持

就是說本來你這個程式是呼叫一個什麼什麼dll裡面的一個什麼什麼函式來實現一個什麼什麼功能,黑客通過分析你的PE格式或者elf格式發現了,然後就寫了一個dll格式的檔案,裡面也準備了一個什麼什麼函式,然後替換你原來裡面的dll檔案|so檔案,然後你呼叫的時候執行的就是黑客準備好的程式碼,這個就叫做程式碼劫持。

相關文章