十二、C++速通秘籍—靜態庫,動態庫

上一章節:

十一、C++速通秘籍—多線程-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/147055932?spm=1001.2014.3001.5502

本章節代碼:

cpp2/library · CuiQingCheng/cppstudy - 碼云 - 開源中國https://gitee.com/cuiqingcheng/cppstudy/tree/master/cpp2/library

目錄

上一章節:

本章節代碼:

一、編程后為什么會引入“庫”,什么是庫?

二、庫分為哪幾類? - 靜態庫,動態庫

1、靜態庫(.a 或.lib)

2、動態庫(.so 或.dll)

三、Linux/windows系統下的庫

1、Linux 下表現形式

2、Windows 下表現形式

四、Linux/Windows下使用靜態庫,什么場景下使用靜態庫?

1、適用場景

2、Linux 下創建和使用靜態庫

2.1、創建靜態庫

2.2、使用靜態庫

3、Windows 下創建和使用靜態庫

3.1、創建靜態庫

3.2、使用靜態庫

五、Linux/Windows下使用動態庫,什么場景下使用動態庫?

1、適用場景

2、Linux 下創建和使用動態庫

2.1、創建動態庫

2.1、使用動態庫

3、Windows 下創建和使用動態庫

3.1、創建動態庫

六、靜態庫,與動態庫二者的區別

內存占用

部署難度

運行效率

可維護性

七、總結


一、編程后為什么會引入“庫”,什么是庫?

????????想象一下你是一位超級大廚,每次做飯都要從頭開始種糧食、養牲畜、采摘蔬菜,那得花費多少時間和精力呀!在編程的世界里也是如此,如果每次編寫程序都要從頭開始實現一些常用的功能,比如文件讀寫、數學計算等,那程序員可就太累啦。于是,“庫”就應運而生了。

????????庫就像是一個裝滿各種工具的百寶箱,里面存放著已經編寫好的代碼,這些代碼實現了各種各樣的功能。當程序員需要使用某個功能時,不需要自己重新編寫代碼,只需要從這個百寶箱里拿出對應的工具(也就是調用庫中的代碼)就可以了。比如說,在 C++ 中,我們之前已經接觸過std標準庫,就提供了很多常用的功能,像字符串處理、容器管理等。你只需要包含相應的頭文件,就可以使用這些功能,就像大廚從廚房里拿出現成的調料一樣方便。

二、庫分為哪幾類? - 靜態庫,動態庫

庫主要分為兩類:靜態庫和動態庫,它們就像是兩種不同類型的百寶箱。

1、靜態庫(.a 或.lib)

????????靜態庫就像是一個可以被復制的百寶箱。當你使用靜態庫時,編譯器會把靜態庫中的代碼完整地復制到你的可執行文件中。這就好比你把百寶箱里的工具都拿出來,放進自己的口袋里,以后無論走到哪里,都可以隨時使用這些工具,不需要再依賴原來的百寶箱。

2、動態庫(.so 或.dll)

????????動態庫則像是一個共享的百寶箱,存放在一個公共的地方。當你的程序需要使用動態庫中的代碼時,程序會在運行時去這個公共的地方查找并加載所需的代碼。這就好比你需要某個工具時,不需要把整個百寶箱都拿走,只需要去公共的地方借用一下工具,用完后再還回去。

三、Linux/windows系統下的庫

1、Linux 下表現形式

在 Linux 系統中,靜態庫的文件擴展名通常是 `.a`,例如 `libexample.a`;動態庫的文件擴展名通常是 `.so`,例如 `libexample.so`。這些庫文件一般存放在 `/usr/lib` 或 `/usr/local/lib` 等目錄下。

2、Windows 下表現形式

在 Windows 系統中,靜態庫的文件擴展名是 `.lib`,例如 `example.lib`;動態庫的文件擴展名是 `.dll`,例如 `example.dll`。這些庫文件通常存放在系統目錄(如 `C:\Windows\System32`)或程序的安裝目錄下

下面是一個簡單的對比圖:

系統

靜態庫擴展名

動態庫擴展名

Linux

.a

.so

Windows

.lib

.dll

四、Linux/Windows下使用靜態庫,什么場景下使用靜態庫?

1、適用場景

當你需要將程序打包成一個獨立的可執行文件,并且不希望依賴外部的庫文件時,就可以使用靜態庫。比如你開發了一個小型的游戲,希望用戶下載后可以直接運行,不需要額外安裝其他庫,這時就可以使用靜態庫。

2、Linux 下創建和使用靜態庫

2.1、創建靜態庫

假設我們有一個簡單的 C++ 函數 `add`,用于計算兩個整數的和,代碼如下:

add.cpp

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

首先,將 `add.cpp` 編譯成目標文件:(add.o)

g++ -c add.cpp -o add.o

然后,使用 `ar` 工具將目標文件打包成靜態庫:

ar rcs libadd.a add.o

這樣,我們就創建了一個名為 `libadd.a` 的靜態庫。

2.2、使用靜態庫

現在,我們來編寫一個主程序 `main.cpp` 來使用這個靜態庫:

main.cpp

#include <iostream>// 聲明 add 函數
extern int add(int a, int b);int main() {int result = add(3, 5);std::cout << "3 + 5 = " << result << std::endl;return 0;
}

編譯并鏈接靜態庫:

g++ main.cpp -L. -ladd -o main

其中,`-L.` 表示在當前目錄下查找庫文件,`-ladd` 表示鏈接名為 `libadd.a` 的靜態庫。最后,運行可執行文件:

./main

3、Windows 下創建和使用靜態庫

3.1、創建靜態庫

同樣使用上面的 `add.cpp` 代碼,打開 VisualCode,創建一個 `add.cpp`文件。

代碼:

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

這里編譯生成.lib,這里需要修改VsCode,中的tasks.json;

通過這個文件創建了兩個編譯任務:create_targe_file/create_static_lib

{"tasks": [{ // 生成目標文件"type": "shell","label": "create_target_file","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c","${file}","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true}},{ // 生成靜態庫"label": "create_static_lib","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\ar.exe","args": ["rcs","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.lib","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"}],"version": "2.0.0"
}

(1)、打開命令面板(Ctrl+Shift+P)

(2)、輸入?Tasks: Run Task?并選擇?create_target_file

(3)、創建靜態庫,跟步驟2相同選擇create_static_lib

3.2、使用靜態庫

創建一個staticEx.cpp

// 鏈接靜態庫
#include <iostream>// 聲明 addWin 函數
extern "C" int addWin(int a, int b);int main() {int result = addWin(5, 5);std::cout << "5 + 5 = " << result << std::endl;return 0;
}

配置tasks.json:

{"tasks": [{ // 生成目標文件"type": "shell","label": "create_target_file","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c","${file}","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true}},{ // 生成靜態庫"label": "create_static_lib","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\ar.exe","args": ["rcs","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.lib","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"},{ // 生成可執行文件"label": "create_exe_file","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c",   // 編譯參數"${file}","-L${fileDirname}\\..\\..\\build","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.exe","-static"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"}],"version": "2.0.0"
}

五、Linux/Windows下使用動態庫,什么場景下使用動態庫?

1、適用場景

當多個程序需要共享相同的代碼,或者庫文件需要經常更新時,使用動態庫就非常合適。比如操作系統中的一些公共庫,多個程序都可以使用這些庫中的功能,這樣可以節省系統資源。

2、Linux 下創建和使用動態庫

2.1、創建動態庫

還是使用上面的 `add.cpp` 代碼,將其編譯成動態庫:

g++ -fPIC -c add.cpp -o add.o
g++ -shared -o libadd.so add.o

其中,`-fPIC` 選項用于生成位置無關代碼,`-shared` 選項用于創建動態庫。

2.1、使用動態庫

編寫主程序 `main.cpp`:

// main.cpp
#include <iostream>// 聲明 add 函數
extern int add(int a, int b);int main() {int result = add(9, 8);std::cout << "9 + 8 = " << result << std::endl;return 0;
}

編譯并鏈接動態庫:


g++ main.cpp -L. -ladd -o mainso

運行程序前,需要設置動態庫的搜索路徑:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
./main

3、Windows 下創建和使用動態庫

3.1、創建動態庫

在 VsCode 中創建兩個文件`dyAdd.h/dyAdd.cpp`, 在dyAdd.h中添加一個導出函數的聲明,dyAdd.cpp中實現函數功能:

dyAdd.h

// 動態庫
#ifndef _DYADD_H_
#define _DYADD_H_#ifdef DYADD_DLL_EXPORTS
#define DYADD_API __declspec(dllimport)
#else
#define DYADD_API __declspec(dllexport) // 導出
#endifextern "C" DYADD_API int add(int a, int b);#endif

dyAdd.cpp

#include "dyAdd.h"extern "C" DYADD_API int add(int a, int b)
{return a + b;
}

tasks.json

{"tasks": [{ // 生成目標文件"type": "shell","label": "create_target_file","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c","${file}","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o","-DDYADD_EXPORTS" // 添加此行以定義 DYADD_EXPORTS 宏],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true}},{ // 生成動態庫"label": "create_dynamic_lib","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-g","-shared","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.dll"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"},{ // 通過動態庫生成可執行文件"label": "create_exe_dyfile","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-g","${file}","-I${fileDirname}","-L${fileDirname}\\..\\..\\build","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.exe","-ladd"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"}],"version": "2.0.0"
}

這里第一步,第二步,執行后生成了dyAdd.dll,以及編譯的中間文件dyAll.o,編譯方法都是通過控制面板按步驟生成:

使用動態庫

dynamicEx.cpp

#include <iostream>
#include <windows.h>// 動態加載
typedef int (*AddFunction)(int, int);int main() {HINSTANCE hDLL = LoadLibrary("dyAdd.dll");if (hDLL != NULL) {AddFunction add = (AddFunction)GetProcAddress(hDLL, "add");if (add != NULL) {int result = add(3, 5);std::cout << "3 + 5 = " << result << std::endl;}else {std::cout << "Failed to get add function address." << std::endl;}FreeLibrary(hDLL);}return 0;
}

編譯并運行程序

六、靜態庫,與動態庫二者的區別

內存占用

靜態庫會將代碼復制到可執行文件中,導致可執行文件體積較大,占用更多的磁盤空間;而動態庫在多個程序間共享,只需要在內存中加載一份,節省了磁盤空間和內存資源。

部署難度

靜態庫部署簡單,可執行文件不依賴外部庫文件,用戶只需要運行可執行文件即可;動態庫部署時需要確保庫文件存在于系統的指定路徑中,否則程序可能無法正常運行。

運行效率

靜態庫的代碼在編譯時就已經鏈接到可執行文件中,運行時無需額外加載,效率相對較高;動態庫在運行時需要加載,會有一定的性能開銷。

可維護性

如果庫文件需要更新,使用靜態庫的程序需要重新編譯;而使用動態庫的程序只需要替換庫文件即可,不需要重新編譯。

下面是一個對比表格:

比較項

靜態庫

動態庫

內存占用

部署難度

簡單

復雜

運行效率

可維護性

七、總結

????????掌握靜態庫和動態庫的使用,能讓你的 C++ 編程之路更加順暢,就像大廚擁有了得心應手的工具,做出更加美味的菜肴一樣!希望通過這篇博客,你能對靜態庫和動態庫有更深入的理解。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75517.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75517.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75517.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

什么是繼承?js中有哪兒些繼承?

1、什么是繼承&#xff1f; 繼承是面向對象軟件技術中的一個概念。 2、js中有哪兒些繼承&#xff1f; js中的繼承有ES6的類class的繼承、原型鏈繼承、構造函數繼承、組合繼承、寄生組合繼承。 2.1 ES6中類的繼承 class Parent {constructor() {this.age 18;} }class Chil…

Linux進程通信入門:匿名管道的原理、實現與應用場景

Linux系列 文章目錄 Linux系列前言一、進程通信的目的二、進程通信的原理2.1 進程通信是什么2.2 匿名管道通訊的原理 三、進程通訊的使用總結 前言 Linux進程間同通訊&#xff08;IPC&#xff09;是多個進程之間交換數據和協調行為的重要機制&#xff0c;是我們學習Linux操作系…

探秘Transformer系列之(26)--- KV Cache優化 之 PD分離or合并

探秘Transformer系列之&#xff08;26&#xff09;— KV Cache優化 之 PD分離or合并 文章目錄 探秘Transformer系列之&#xff08;26&#xff09;--- KV Cache優化 之 PD分離or合并0x00 概述0x01 背景知識1.1 自回歸&迭代1.2 KV Cache 0x02 靜態批處理2.1 調度策略2.2 問題…

十大PDF解析工具在不同文檔類別中的比較研究

PDF解析對于包括文檔分類、信息提取和檢索在內的多種自然語言處理任務至關重要&#xff0c;尤其是RAG的背景下。盡管存在各種PDF解析工具&#xff0c;但它們在不同文檔類型中的有效性仍缺乏充分研究&#xff0c;尤其是超出學術文檔范疇。通過使用DocLayNet數據集&#xff0c;比…

HarmonyOS-ArkUI 裝飾器V2 @ObservedV2與@Trace裝飾器

參考文檔: 文檔中心https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/arkts-new-observedv2-and-trace-V14#trace%E8%A3%85%E9%A5%B0%E5%AF%B9%E8%B1%A1%E6%95%B0%E7%BB%84由于V2的裝飾器比V1的裝飾器更加易用,盡管學習的過程中用到的都是V1的裝飾器,但…

GPT - GPT(Generative Pre-trained Transformer)模型框架

本節代碼主要為實現了一個簡化版的 GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型。GPT 是一種基于 Transformer 架構的語言生成模型&#xff0c;主要用于生成自然語言文本。 1. 模型結構 初始化部分 class GPT(nn.Module):def __init__(self, vocab…

基于FPGA的六層電梯智能控制系統 矩陣鍵盤-數碼管 上板仿真均驗證通過

基于FPGA的六層電梯智能控制系統 前言一、整體方案二、軟件設計總結 前言 本設計基于FPGA實現了一個完整的六層電梯智能控制系統&#xff0c;旨在解決傳統電梯控制系統在別墅環境中存在的個性化控制不足、響應速度慢等問題。系統采用Verilog HDL語言編程&#xff0c;基于Cyclo…

車載通信系統中基于ISO26262的功能安全與抗輻照協同設計研究

摘要&#xff1a;隨著智能網聯汽車的快速發展&#xff0c;車載通信系統正面臨著功能安全與抗輻照設計的雙重挑戰。在高可靠性要求的車載應用場景下&#xff0c;如何實現功能安全標準與抗輻照技術的協同優化&#xff0c;構建滿足ISO26262安全完整性等級要求的可靠通信架構&#…

Node.js種cluster模塊詳解

Node.js 中 cluster 模塊全部 API 詳解 1. 模塊屬性 const cluster require(cluster);// 1. isMaster // 判斷當前進程是否為主進程 console.log(是否為主進程:, cluster.isMaster);// 2. isWorker // 判斷當前進程是否為工作進程 console.log(是否為工作進程:, cluster.isW…

融合動態權重與抗刷機制的網文評分系統——基于優書網、IMDB與Reddit的混合算法實踐

? Yumuing 博客 &#x1f680; 探索技術的每一個角落&#xff0c;解碼世界的每一種可能&#xff01; &#x1f48c; 如果你對 AI 充滿好奇&#xff0c;歡迎關注博主&#xff0c;訂閱專欄&#xff0c;讓我們一起開啟這段奇妙的旅程&#xff01; 以權威用戶為核心&#xff0c;時…

使用Golang打包jar應用

文章目錄 背景Go 的 go:embed 功能介紹與打包 JAR 文件示例1. go:embed 基礎介紹基本特性基本語法 2. 嵌入 JAR 文件示例項目結構代碼實現 3. 高級用法&#xff1a;嵌入多個文件或目錄4. 使用注意事項5. 實際應用場景6. 完整示例&#xff1a;運行嵌入的JAR 背景 想把自己的一個…

前端大屏可視化項目 局部全屏(指定盒子全屏)

需求是這樣的&#xff0c;我用的項目是vue admin 項目 現在需要在做大屏項目 不希望顯示除了大屏的其他東西 于是想了這個辦法 至于大屏適配問題 請看我文章 底部的代碼直接復制就可以運行 vue2 px轉rem 大屏適配方案 postcss-pxtorem-CSDN博客 <template><div …

《2025藍橋杯C++B組:D:產值調整》

**作者的個人gitee**?? 作者的算法講解主頁?? 每日一言&#xff1a;“淚眼問花花不語&#xff0c;亂紅飛過秋千去&#x1f338;&#x1f338;” 題目 二.解題策略 本題比較簡單&#xff0c;我的思路是寫三個函數分別計算黃金白銀銅一次新產值&#xff0c;通過k次循環即可獲…

[VTK] 四元素實現旋轉平移

VTK 實現旋轉&#xff0c;有四元數的方案&#xff0c;也有 vtkTransform 的方案&#xff1b;主要示例代碼如下&#xff1a; //構造旋轉四元數vtkQuaterniond rotation;rotation.SetRotationAngleAndAxis(vtkMath::RadiansFromDegrees(90.0),0.0, 1.0, 0.0);//構造旋轉點四元數v…

華為hcie證書的有效期怎么判斷?

在ICT行業&#xff0c;華為HCIE證書堪稱含金量極高的“敲門磚”&#xff0c;擁有它往往意味著在職場上更上一層樓。然而&#xff0c;很多人在辛苦考取HCIE證書后&#xff0c;卻對其有效期相關事宜一知半解。今天&#xff0c;咱們就來好好嘮嘮華為HCIE證書的有效期怎么判斷這個關…

【精品PPT】2025固態電池知識體系及最佳實踐PPT合集(36份).zip

精品推薦&#xff0c;2025固態電池知識體系及最佳實踐PPT合集&#xff0c;共36份。供大家學習參考。 1、中科院化學所郭玉國研究員&#xff1a;固態金屬鋰電池及其關鍵材料.pdf 2、中科院物理所-李泓固態電池.pdf 3、全固態電池技術研究進展.pdf 4、全固態電池生產工藝.pdf 5、…

MySQL 中為產品添加靈活的自定義屬性(如 color/size)

方案 1&#xff1a;EAV 模型&#xff08;最靈活但較復雜&#xff09; 適合需要無限擴展自定義屬性的場景 -- 產品表 CREATE TABLE products (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100),price DECIMAL(10,2) );-- 屬性名表 CREATE TABLE attributes (id INT PRIMA…

CSPM認證對項目論證的范式革新:從合規審查到價值創造的戰略躍遷

引言 在數字化轉型浪潮中&#xff0c;全球企業每年因項目論證缺陷導致的損失高達1.7萬億美元&#xff08;Gartner 2023&#xff09;。CSPM&#xff08;Certified Strategic Project Manager&#xff09;認證體系通過結構化方法論&#xff0c;將傳統的項目可行性評估升級為戰略…

CLIP中的Zero-Shot Learning原理

CLIP&#xff08;Contrastive Language-Image Pretraining&#xff09;是一種由OpenAI提出的多模態模型&#xff0c;它通過對比學習的方式同時學習圖像和文本的表示&#xff0c;并且能在多種任務中進行零樣本學習&#xff08;Zero-Shot Learning&#xff09;。CLIP模型的核心創…

spring mvc 中 RestTemplate 全面詳解及示例

RestTemplate 全面詳解及示例 1. RestTemplate 簡介 定義&#xff1a;Spring 提供的同步 HTTP 客戶端&#xff0c;支持多種 HTTP 方法&#xff08;GET/POST/PUT/DELETE 等&#xff09;&#xff0c;用于調用 RESTful API。核心特性&#xff1a; 支持請求頭、請求體、URI 參數的…