這次分享的宗旨是——讓大家學會創建與使用靜態庫、動態庫,知道靜態庫與動態庫的區別,知道使用的時候如何選擇。這裡不深入介紹靜態庫、動態庫的底層格式,內存布局等,有興趣的同學,推薦一本書《程序員的自我修養——鏈接、裝載與庫》。
什麼是庫
庫是寫好的現有的,成熟的,可以復用的代碼。現實中每個程序都要依賴很多基礎的底層庫,不可能每個人的代碼都從零開始,因此庫的存在意義非同尋常。
本質上來說庫是一種可執行代碼的二進制形式,可以被操作系統載入內存執行。庫有兩種:靜態庫.a、.lib)和動態庫.so、.dll)。
所謂靜態、動態是指鏈接。回顧一下,將一個程序編譯成可執行程序的步驟:
靜態庫
之所以成為靜態庫】,是因為在鏈接階段,會將匯編生成的目標文件.o與引用到的庫一起鏈接打包到可執行文件中。因此對應的鏈接方式稱為靜態鏈接。
試想一下,靜態庫與匯編生成的目標文件一起鏈接為可執行文件,那麼靜態庫必定跟.o文件格式相似。其實一個靜態庫可以簡單看成是一組目標文件.o/.obj文件)的集合,即很多目標文件經過壓縮打包後形成的一個文件。靜態庫特點總結:
靜態庫對函數庫的鏈接是放在編譯時期完成的。
程序在運行時與函數庫再無瓜葛,移植方便。
浪費空間和資源,因為所有相關的目標文件與牽涉到的函數庫被鏈接合成一個可執行文件。
下面編寫一些簡單的四則運算C++類,將其編譯成靜態庫給他人用,頭文件如下所示:
- #pragma once
- class StaticMath
- {
- public:
- StaticMath(void);
- ~StaticMath(void);
- static double add(double a, double b);//加法
- static double sub(double a, double b);//減法
- static double mul(double a, double b);//乘法
- static double div(double a, double b);//除法
- void print();
- };
inux下使用ar工具、Windows下vs使用lib.exe,將目標文件壓縮到一起,並且對其進行編號和索引,以便於查找和檢索。一般創建靜態庫的步驟如圖所示: