庫是預先編譯好的可復用二進制代碼。現代軟體開發離不開基礎庫,避免重複造輪子。本質上,庫是可執行代碼的二進制形式,可被作業系統載入記憶體執行。
| 特性 | 靜態庫 (.a / .lib) | 動態庫 (.so / .dll) |
|---|---|---|
| 鏈接階段 | 編譯時(靜態鏈接) | 運行時(動態鏈接) |
| 可執行檔體積 | 較大(含庫代碼) | 較小(僅符號引用) |
| 部署更新 | 全量更新,需重新編譯發布 | 增量更新,替換 .so/.dll 即可 |
| 記憶體共享 | 每進程獨佔副本 | 多進程共享單一實例 |
| 符號解析 | 鏈接器完成 | 動態鏈接器運行時完成 |
lib[name].alib[name].so,另有 soname(如 libfoo.so.1)與鏈接名(libfoo.so)# 1. 編譯目標文件 g++ -c StaticMath.cpp -o StaticMath.o # 2. 打包為 .a ar -crv libstaticmath.a StaticMath.o # 3. 使用 g++ Test.cpp -L./lib -lstaticmath -o test
# 1. 編譯位置無關代碼 g++ -fPIC -c DynamicMath.cpp -o DynamicMath.o # 2. 生成 .so g++ -shared -o libdynmath.so DynamicMath.o # 3. 使用(需解決運行時尋找路徑) g++ Test.cpp -L./lib -ldynmath -o test # 運行前設置路徑 export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH # 或永久配置 echo "/path/to/lib" >> /etc/ld.so.conf && ldconfig
StaticMath.lib(含實際代碼)StaticMath.libDllMain 入口,導出函數加 __declspec(dllexport)DynamicMath.dll(代碼)+ DynamicMath.lib(導入庫,僅符號表)DynamicMath.lib,運行時 .dll 需在 PATH 中隱式調用:編譯時鏈接 .lib,運行時自動載入。
顯式調用:代碼中手動載入、獲取函數指針、釋放。
| 平台 | 載入 | 獲取符號 | 釋放 |
|---|---|---|---|
| Linux | dlopen | dlsym | dlclose |
| Windows | LoadLibrary | GetProcAddress | FreeLibrary |
extern "C" 導出 C 風格符號建議:能用隱式調用就不用顯式,能用靜態庫就不用動態庫,除非有明確熱插拔、插件架構需求。
nm libxxx.a/.so:查看符號表(T=定義、U=未定義、W=弱符號)ldd executable:查看可執行文件依賴的動態庫g++ -shared -fPIC -o libxxx.so src.cpp:一步生成動態庫