C++靜態庫與動態庫的區別


在日常開發中,其實大部分時間我們都會和第三方庫或系統庫打交道。在 Android 開發音視頻開發領域,一般會用到 FFmepg、OpenCV、OpenGL 等等開源庫, 我們一般都會編譯成動態庫共我們程序使用。對於類 unix 系統,靜態庫為 .a, 動態庫為 .so。而 windows 系統靜態庫為 .lib, 動態庫為.dll。
靜態鏈接庫
回顧程序編譯的四個步驟:
預編譯 -> 編譯 -> 匯編 -> 鏈接 
靜態庫和動態庫就是在鏈接階段行為不同,靜態庫會在鏈接階段將匯編生成的目標文件 .o 與引用的庫一起鏈接打包到可執行文件中。靜態庫其實就是一系列目標文件的集合,可以用 ar 工具打包生成。靜態庫特點有:

  • 靜態庫對函數的鏈接在編譯時期完成
  • 程序在運行時與函數庫再無關系
  • 浪費資源空間,因為所有相關的目標文件都會被鏈接到一個可執行文件中
 我們來看一個例子:
// 頭文件 Math.hpp
#ifndef Math_hpp
#define Math_hpp
#include <stdio.h>
extern int add(int a, int b);
#endif /* Math_hpp */


 
// Math.hpp 實現文件
#include "Math.hpp"

int add(int a, int b)
{
    return a + b;
}



// main.cpp main 函數入口
#include <iostream>

extern int add(int a, int b);

int main(int argc, const char * argv[]) {
    // insert code here...
    
    using std::cout;
    using std::endl;

    cout << "add 2 3: " << add(2, 3) << endl;

    
    return 0;
}

  

  • -t: 按順序顯示歸檔中的文件名
  • -d: 從歸檔中刪除指定文件

鏈接靜態庫
clang++ main.cpp -L. -lmath -o main 
生成成功后,執行 ./main 執行


解釋下參數:

  • -L: 表示要鏈接的庫所在目錄,如果不指定就會在系統 usr/lib 或 usr/local/lib 下查找
  • -l: 指定鏈接時的動態庫或靜態庫,如果有動態將會優先被鏈接

動態鏈接庫
使用動態庫的原因,正式因為靜態庫很耗費內存空間,並且靜態庫更新簡直是災難,如果庫源碼發生變動,那么靜態庫將不得不重新生成。
動態庫特點如下:

  • 延遲加載一些庫函數,既用到才加載
  • 動態庫可以同時被多個程序共享,節省內存

借着上面的例子,顯示動態庫的使用,首先,生成動態鏈接庫文件
clang++ Math.o -shared -fPIC -Wall -o libmath.so 
生成動態鏈接庫文件后,再使用如下命令生成可執行文件
clang++ main.cpp -L. -lmath -o main 
執行 ./main
參數說明:

  • -shared: 表示生成的是動態鏈接庫
  • -fPIC: 生成位置獨立的代碼,用於編譯共享庫。在任意內存空間都可以被加載
  • -Wall: 生成所有警告信息


如果覺得本文不錯,那就點個關注吧~ 關於更多的面試資料我已經整理成相關文檔,需要的朋友可以點擊獲取

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM