首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 靜態庫與動態庫完整指南:創建、使用、區別與選擇

     編輯:關於C++

什麼是庫?

庫是預先編譯好的可復用二進制代碼。現代軟體開發離不開基礎庫,避免重複造輪子。本質上,庫是可執行代碼的二進制形式,可被作業系統載入記憶體執行。

核心區別:鏈接時機

特性靜態庫 (.a / .lib)動態庫 (.so / .dll)
鏈接階段編譯時(靜態鏈接)運行時(動態鏈接)
可執行檔體積較大(含庫代碼)較小(僅符號引用)
部署更新全量更新,需重新編譯發布增量更新,替換 .so/.dll 即可
記憶體共享每進程獨佔副本多進程共享單一實例
符號解析鏈接器完成動態鏈接器運行時完成

Linux 平台實戰

命名規範

  • 靜態庫:lib[name].a
  • 動態庫:lib[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

Windows 平台實戰

靜態庫

  • VS 專案屬性 → 配置類型 → 靜態庫
  • 生成 StaticMath.lib(含實際代碼)
  • 使用:屬性 → 鏈接器 → 輸入 → 附加依賴項添加 StaticMath.lib

動態庫

  • VS 專案屬性 → 配置類型 → 動態庫
  • 需 DllMain 入口,導出函數加 __declspec(dllexport)
  • 生成 DynamicMath.dll(代碼)+ DynamicMath.lib(導入庫,僅符號表)
  • 使用:鏈接器輸入添加 DynamicMath.lib,運行時 .dll 需在 PATH 中

動態庫顯式調用

隱式調用:編譯時鏈接 .lib,運行時自動載入。
顯式調用:代碼中手動載入、獲取函數指針、釋放。

平台載入獲取符號釋放
Linuxdlopendlsymdlclose
WindowsLoadLibraryGetProcAddressFreeLibrary

C++ 顯式調用難點

  1. Name Mangling:C++ 符號經過修飾,需用 extern "C" 導出 C 風格符號
  2. 類無法直接載入:需導出工廠函數返回對象指針,極其繁瑣且危險

建議:能用隱式調用就不用顯式,能用靜態庫就不用動態庫,除非有明確熱插拔、插件架構需求。

常用工具命令

  • nm libxxx.a/.so:查看符號表(T=定義、U=未定義、W=弱符號)
  • ldd executable:查看可執行文件依賴的動態庫
  • g++ -shared -fPIC -o libxxx.so src.cpp:一步生成動態庫

總結選擇指南

  • **靜態庫**:嵌入式、無依賴部署、極致性能、庫極小
  • **動態庫**:大型系統、插件架構、多進程共享、頻繁熱更新、記憶體受限
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved