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

C++ 靜態庫與動態庫完整指南:創建、使用、顯式調用、選型策略

     編輯:關於C++

核心區別:鏈接時機

特性靜態庫 (.a/.lib)動態庫 (.so/.dll)
鏈接階段編譯時 (靜態鏈接)運行時 (動態鏈接)
代碼副本嵌入可執行文件內存共享一份
可執行體積較大較小
部署更新全量更新增量更新 (替換 .so/.dll)
依賴關系無運行時依賴需庫文件存在
符號解析鏈接器完成動態鏈接器完成

Linux 平台實戰

靜態庫

# 創建
g++ -c StaticMath.cpp -o StaticMath.o
ar -crv libstaticmath.a StaticMath.o

# 使用
g++ test.cpp -L. -lstaticmath -o test
./test

動態庫

# 創建 (-fPIC 位置無關代碼,-shared 生成共享庫)
g++ -fPIC -shared DynamicMath.cpp -o libdynmath.so

# 使用 (需庫在搜索路徑)
g++ test.cpp -L. -ldynmath -o test
# 運行時找不到庫解決:
# 1. cp libdynmath.so /usr/lib/
# 2. export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
# 3. 編輯 /etc/ld.so.conf + ldconfig

Windows (MSVC) 平台實戰

靜態庫 (.lib)

  • VS 項目屬性 → 配置類型 → 靜態庫 (.lib)
  • 或命令行:cl /c StaticMath.cpp → lib StaticMath.obj

動態庫 (.dll + .lib 導入庫)

  • VS 項目屬性 → 配置類型 → 動態庫 (.dll)
  • 導出函數需 __declspec(dllexport)
  • 生成:DynamicMath.dll (運行時代碼) + DynamicMath.lib (導入庫,僅符號表)
  • 使用:鏈接 .lib,運行時載入 .dll

關鍵區別

StaticMath.lib   190 KB  ← 實際代碼+符號表
DynamicMath.lib    3 KB  ← 僅導入符號表 (地址存根)
DynamicMath.dll  100 KB  ← 實際代碼

動態庫顯式調用 (運行時加載)

Linux: dlopen 族

#include 
void* handle = dlopen("./libdynmath.so", RTLD_LAZY);
auto add = (double(*)(double,double))dlsym(handle, "_ZN10DynamicMath3addEdd"); // mangled name
add(1.0, 2.0);
dlclose(handle);

C++ name mangling 導致符號難以預測,建議 extern "C" 導出純 C 接口:

extern "C" double add_wrapper(double a, double b) { return DynamicMath::add(a,b); }

Windows: LoadLibrary 族

HMODULE h = LoadLibrary("DynamicMath.dll");
auto add = (double(*)(double,double))GetProcAddress(h, "add_wrapper");
add(1.0, 2.0);
FreeLibrary(h);

顯式調用 C++ 類的困境

  • 無標準 API 實例化類 (需工廠函數導出)
  • 跨 DLL 邊界傳遞 C++ 對象極其危險 (內存分配器、異常、STL 版本不匹配)
  • 建議:能用隱式鏈接就不用顯式;必須顯式時,導出 C 接口封裝

常用工具命令

命令用途
nm libxxx.a查看符號表 (T=定義, U=未定義, W=弱符號)
ldd a.out查看動態依賴
objdump -T libxxx.so查看動態符號表
dumpbin /EXPORTS xxx.dllWindows 查看導出函數

選型決策樹

是否需插件/熱更新/多進程共享? → 動態庫
是否嵌入式/無文件系統/極致性能? → 靜態庫
第三方庫是否僅提供動態版? → 動態庫
是否輕量工具/單文件分發? → 靜態庫
預設建議:動態庫 (現代系統內存豐富,共享收益大)

避坑指南

  1. 循環依賴:動態庫間循環依賴會導致載入失敗
  2. 符號衝突:多個動態庫導出同名符號,用 -Bsymbolic 或版本腳本
  3. ABI 兼容:動態庫升級保持接口兼容,否則需重新編譯依賴方
  4. Windows DLL Hell:應用程序目錄優先搜索,避免系統目錄版本衝突
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved