程式碼分發方式
動態庫與靜態庫唯一的區別就是動態庫多了個dll檔案
庫的作用
- 程式碼解耦、重用
- 對外提供服務(export)
- 典型應用:exe呼叫dll。我們開啟軟體目錄一堆dll,少量exe就是這個道理
對於小軟體,它會把程式碼都寫到exe裡面,但是大軟體程式碼是需要重用的。
以火絨安全為例:
庫的分類(形式)
-
靜態庫:與exe打包成exe(一個檔案),windows就是.lib檔案
linux就是.a檔案
它們在呼叫時會與它們的呼叫者.exe打包成一個.exe
【其實windows會變成pe可執行檔案,linux是.elf可執行檔案,這裡為了方便理解這麼說】 -
動態連結庫(共享庫)
與exe是獨立的2個檔案
windows就是.dll檔案
linux就是.so檔案
動態庫就是當你呼叫dll檔案的時候,別人也可以呼叫,也就是說是可以重用的,而靜態庫是不可以的。
靜態庫與動態庫的區別
- 靜態庫
1、優點:程式碼合併到模組中,無零散檔案。
2、缺點:模組體積變大,當多個模組使用該庫時,記憶體中有多份程式碼。
- 動態庫
1、優點:模組體積幾乎不變,當多個模組使用該庫時,記憶體中只存在一份程式碼。
2、缺點:程式碼在單獨檔案中,有零散檔案。
總結:
靜態庫的程式碼有改動時,所有依賴它的檔案都要重新編譯。動態庫不用(某些更改),可以只更新動態庫檔案(.dll檔案)。
C/C++到可執行程式的過程
靜態庫配置方法
首先我們編譯好了一份靜態庫檔案,只有.h檔案和.lib檔案
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)
第二種:【推薦】
我們點選專案->屬性,然後步驟如下
我們在這裡寫下標頭檔案的目錄(只需寫到資料夾路徑,不需寫到檔案路徑)
然後標頭檔案就配置好了
接下來是lib檔案,lib檔案是給連結器看的,我們需要配置它的目錄
同理,在這裡填上lib資料夾路徑
然後還需要在輸入->附加依賴項中寫上lib檔案的名字
這樣就配置好了,但是需要注意這裡的配置是要和專案配合使用的
Debug配Debug,X86配Win32
然後接下來我們就可以像正常使用別的庫一樣,使用它
程式碼:
#include <windows.h>
#include <iostream>
#include <StaticLib.h>
using namespace std;
int main()
{
cout << Add(1,1) << endl;
return 0;
}
然後就可以正常執行了
動態庫配置方法
主體流程基本差不多,只是多了個dll檔案的配置
可以看到這裡有三個檔案
.h檔案和.lib檔案與靜態相同這裡就不再演示【Dll.dll檔案我們不需要配置】
我們需要注意要把dll檔案複製到專案編譯後的專案資料夾裡
程式碼:
#include <windows.h>
#include <iostream>
#include <Dll.h>
using namespace std;
int main()
{
cout << Add(1,1) << endl;
return 0;
}
執行:
注意:
動態庫的特點是需要dll檔案與exe檔案在一起或者是在一些特定的dll搜尋路徑下即可。
衍生技術
黑客hook dll:程式碼替換或叫程式碼劫持
就是說本來你這個程式是呼叫一個什麼什麼dll裡面的一個什麼什麼函式來實現一個什麼什麼功能,黑客通過分析你的PE格式或者elf格式發現了,然後就寫了一個dll格式的檔案,裡面也準備了一個什麼什麼函式,然後替換你原來裡面的dll檔案|so檔案,然後你呼叫的時候執行的就是黑客準備好的程式碼,這個就叫做程式碼劫持。