天天看點

C++ 靜态庫 與 動态庫

目錄

  • 基礎知識
    • 參考内容
    • 動态庫 與 靜态庫
  • 靜态庫 建立 與 使用
    • 靜态庫 的 建立
    • 靜态庫 的 使用
  • 動态庫 建立 與 使用
    • 動态庫 的 建立
    • 動态庫 的 使用
    • __declspec(dllexport) 與 __declspec(dllimport)

C++靜态庫與動态庫的差別

通俗了解動态庫與靜态庫差別

靜态庫與動态庫的優缺點

動态庫和靜态庫的了解

《程式員的自我修養——連結、裝載與庫》

lib 和 dll 的差別、生成以及使用詳解

C++建立和使用動态連結庫

C++動态庫封裝及調用

靜态庫 在 unix系統中 是 .a 檔案,在window系統是 .lib檔案

動态庫 在 unix系統中 是 .so檔案,在window系統是 .dll檔案

最本質的差別:該庫是否被編譯進目标程式内部

他們之間的差別在于 程式編譯的階段,操作上不同。

  • 程式編譯步驟:預編譯 -> 編譯 -> 彙編 -> 連結
  • 靜态庫和動态庫就是在連結階段行為不同

靜态庫在連結階段将會變生成的目标檔案.o 和 引用到的庫一起連結打包到可執行檔案中。

動态庫隻有在程式運作時 需要使用到庫的時候,才加載庫代碼。

靜态庫 動态庫
特點 靜态庫對函數庫的連結是放在編譯時期完成的 動态庫把對一些庫函數的連結載入推遲到程式運作的時期
優點

1.程式在運作時與函數庫再無瓜葛,移植友善

2.編譯成功的可執行檔案可以獨立運作,而不再需要向外部要求讀取函數庫的内容

3.代碼裝載速度快,執行速度略比動态連結庫快

4.隻需保證在開發者的計算機中有正确的.LIB檔案,在以二進制形式釋出程式時不需考慮在使用者的計算機上.LIB檔案是否存在及版本問題,可避免DLL地獄等問題

1.将一些程式更新變得簡單

2.更加節省記憶體并減少頁面交換

3.可以實作程序之間的資源共享,共用庫

4.産品功能更新角度友善更新,隻要替換對應動态庫即可,不必重新編譯整個可執行檔案

5.DLL檔案與EXE檔案獨立,隻要輸出接口不變(即名稱、參數、傳回值類型和調用約定不變),更換DLL檔案不會對EXE檔案造成任何影響,因而極大地提高了可維護性和可擴充性

6.不同程式設計語言編寫的程式隻要按照函數調用約定就可以調用同一個DLL函數

缺點

1.空間浪費,使用靜态庫的程序相當于複制一份靜态庫代碼到程式中中,如果多個程序都使用,就會多複制幾份

2.更新問題:如果靜态庫liba.lib更新了,是以使用它的應用程式都需要重新編譯、釋出給使用者(對于玩家來說,可能是一個很小的改動,卻導緻整個程式重新下載下傳,全量更新)

1.使用動态連結庫的應用程式不是自完備的,它依賴的DLL子產品也要存在

2.如果使用載入時動态連結,程式啟動時發現DLL不存在,系統将終止程式并給出錯誤資訊

3.速度比靜态連結慢

應用場景 從函數庫內建的角度,若要将釋出的所有子庫(不止一個)內建為一個動态庫向外提供接口,那麼就需要将所有子庫編譯為靜态庫,這樣所有子庫就可以全部編譯進目标動态庫中,由最終的一個內建庫向外提供功能。

适用于大規模的軟體開發,使開發過程獨立、耦合度小,便于不同開發者和開發組織之間進行開發和測試

從産品化的角度,釋出的算法庫或功能庫盡量使動态庫,這樣友善更新和更新,不必重新編譯整個可執行檔案,隻需新版本動态庫替換掉舊動态庫即可

靜态庫 和 動态庫的 建立使用 都是基于 window平台 ,VS實作的

  1. 建立空項目
    C++ 靜态庫 與 動态庫
  2. 編寫所需要的頭檔案 和 cpp檔案
    C++ 靜态庫 與 動态庫
    C++ 靜态庫 與 動态庫
  3. 可以在該項目 寫個main.cpp 測試代碼,後期生成庫之前的時候注釋掉
    C++ 靜态庫 與 動态庫
  4. 打開項目屬性 -》 正常 -》配置類型選擇靜态庫 -》确定
    C++ 靜态庫 與 動态庫
  5. 注釋main函數,重新生成項目
C++ 靜态庫 與 動态庫
  1. 找到對應的 h檔案 和 lib檔案 可以将其提取放到 其他地方

在需要用到 該庫的項目 設定一些配置 ,可以把 h檔案 lib檔案放到項目中一些對應位置
  • 方法一:配置項目屬性
  1. 添加工程的頭檔案目錄:工程---屬性---配置屬性---c/c++---正常---附加包含目錄:加上頭檔案存放目錄。
    C++ 靜态庫 與 動态庫
  2. 添加檔案引用的lib靜态庫路徑:工程---屬性---配置屬性---連結器—正常—附加庫目錄:加上lib檔案存放目錄。
    C++ 靜态庫 與 動态庫
  3. 然後添加工程引用的lib檔案名:工程---屬性---配置屬性---連結器---輸入—附加依賴項:加上lib檔案名。
    C++ 靜态庫 與 動态庫
  4. 使用
    C++ 靜态庫 與 動态庫
  • 方法二:使用編譯語句

    #pragma comment(lib,"./mylib.lib")

  • 方法三:添加工程中

    就像 添加.h和.cpp檔案一樣,把lib檔案添加到工程檔案清單中去.

    切換到"解決方案視圖",--->選中要添加lib的工程-->點選右鍵-->"添加"-->"現有項"-->選擇lib檔案-->确定.

    C++ 靜态庫 與 動态庫

建立 和 配置資訊 和靜态庫類似

  1. 建立一個空項目
  2. 建立需要的頭檔案 和 cpp檔案
  3. 編寫 頭檔案内容
    C++ 靜态庫 與 動态庫
  4. 編寫cpp内容
  5. 在工程屬性,C/C++ => 預處理器 => 預處理定義 中添加預定義宏 DLL_EXPORT
    C++ 靜态庫 與 動态庫
  6. 工程屬性 -》正常 -》 配置類型 設定 動态庫
    C++ 靜态庫 與 動态庫
  7. 生成項目(同理 如果有 main函數,則需要将其注釋掉)
    C++ 靜态庫 與 動态庫

  1. 配置項目屬性 (和靜态庫一緻)

A、添加工程的頭檔案目錄:工程---屬性---配置屬性---c/c++---正常—附加包含目錄:加上頭檔案存放目錄。

B、添加檔案引用的lib靜态庫路徑:工程---屬性---配置屬性—連結器—正常—附加庫目錄:加上lib檔案存放目錄。

C 然後添加工程引用的lib檔案名:工程---屬性---配置屬性---連結器---輸入—附加依賴項:加上lib檔案名。

  1. 将 dll檔案拷到 可執行檔案的目錄下

    否則運作時會出現這個錯誤:

    C++ 靜态庫 與 動态庫

  • 參考内容:

    __declspec(dllimport)的作用到底在哪裡呢

    關于C++的dllexport和dllimport

  • _declspec(dllexport)

聲明一個導出函數,是說這個函數要從本DLL導出。我要給别人用。一般用于dll中省掉在DEF檔案中手工定義導出哪些函數的一個方法。當然,如果你的DLL裡全是C++的類的話,你無法在DEF裡指定導出的函數,隻能用__declspec(dllexport)導出類

  • __declspec(dllimport)

聲明一個導入函數,是說這個函數是從别的DLL導入。一般用于使用某個dll的exe中 不使用 __declspec(dllimport) 也能正确編譯代碼,但使用 __declspec(dllimport) 使編譯器可以生成更好的代碼。編譯器之是以能夠生成更好的代碼,是因為它可以确定函數是否存在于 DLL 中,這使得編譯器可以生成跳過間接尋址級别的代碼,而這些代碼通常會出現在跨 DLL 邊界的函數調用中。但是,必須使用 __declspec(dllimport) 才能導入 DLL 中使用的變量。