鏈接器的工作原理,靜態鏈接與動態鏈接的區別,如何創建和使用動態鏈接庫

鏈接器在程序開發中的作用至關重要,它負責將多個目標文件和庫文件整合成一個可以執行的文件。在深入了解鏈接器的工作原理、靜態鏈接與動態鏈接的區別,以及如何創建和使用動態鏈接庫之前,我們先來概述一下鏈接器的基本功能。

鏈接器的工作原理

鏈接器(Linker) 是負責將一個或多個目標文件與庫文件組合成一個可執行文件的工具。其主要功能包括:

  1. 符號解析:識別并處理程序中所有的符號(函數和變量的名稱),確保每個符號都有唯一的定義。對于引用但未定義的符號(外部符號),鏈接器會在提供的庫或其他目標文件中查找定義。

  2. 重定位:將每個模塊中的代碼和數據地址調整到最終的內存地址。重定位包括代碼中的地址修正和數據段的位置調整,以保證所有引用指向正確的內存位置。

  3. 合并段:將來自不同目標文件的相同類型的段(如代碼段、數據段等)合并成一個連續的段。

  4. 處理庫:將程序需要的庫代碼與目標文件鏈接在一起。鏈接器可以處理兩種類型的庫:靜態庫和動態庫。

  5. 生成可執行文件:最終輸出一個可以在操作系統上運行的可執行文件。

靜態鏈接與動態鏈接的區別

靜態鏈接(Static Linking)動態鏈接(Dynamic Linking) 是鏈接器的兩種工作模式,它們各自有不同的特點和使用場景。

靜態鏈接
  • 概念:在靜態鏈接中,庫代碼在編譯時被復制并嵌入到每個使用它的可執行文件中。這樣,生成的可執行文件包含所有需要的代碼,不依賴外部的庫文件。

  • 優點

    • 獨立性強:生成的可執行文件包含所有依賴,不需要在運行時額外的庫文件。
    • 兼容性好:運行時不依賴于系統中安裝的庫版本,不會遇到“庫版本沖突”問題。
  • 缺點

    • 文件體積大:每個可執行文件都包含完整的庫代碼,導致文件體積增大。
    • 更新麻煩:如果庫有更新,需要重新編譯所有使用該庫的程序。
  • 靜態庫的擴展名

    • Windows: .lib
    • Unix/Linux: .a
動態鏈接
  • 概念:在動態鏈接中,庫代碼在運行時加載,不嵌入到可執行文件中。可執行文件只包含對庫的引用,庫代碼在運行時由操作系統加載。

  • 優點

    • 文件體積小:可執行文件不包含庫代碼,只包含對庫的引用。
    • 易于更新:更新庫不需要重新編譯程序,只需替換庫文件。
    • 內存效率高:多個程序可以共享同一個庫文件的內存實例,減少內存使用。
  • 缺點

    • 依賴性強:可執行文件在運行時需要能夠找到并加載正確版本的庫文件。
    • 兼容性問題:庫文件版本不匹配可能導致程序運行失敗。
  • 動態庫的擴展名

    • Windows: .dll(Dynamic-Link Library)
    • Unix/Linux: .so(Shared Object)

創建和使用動態鏈接庫

創建動態鏈接庫

在不同的操作系統上,創建動態鏈接庫的方法略有不同。以下是一些常見的步驟和命令:

在 Linux 上創建動態鏈接庫
  1. 編寫庫代碼

    創建一個C++源文件,包含我們要放在動態庫中的函數。

    // example.cpp
    #include <iostream>void hello() {std::cout << "Hello from the dynamic library!" << std::endl;
    }
    

    2.編譯為目標文件

    使用 -fPIC(Position Independent Code)標志編譯源文件為目標文件。這是創建動態庫的必要步驟,因為動態庫中的代碼需要能夠在任何內存地址加載和執行。

    g++ -c -fPIC example.cpp -o example.o
    

    3.創建動態庫

    使用 -shared 標志將目標文件鏈接為動態庫。

    g++ -shared -o libexample.so example.o
    

生成的動態庫文件 libexample.so 可以在程序中使用。

在 Windows 上創建動態鏈接庫
  1. 編寫庫代碼

    Windows上的代碼編寫與Linux相似,但需要使用__declspec(dllexport)指令來標識導出的函數。

    // example.cpp
    #include <iostream>__declspec(dllexport) void hello() {std::cout << "Hello from the dynamic library!" << std::endl;
    }
    

    2.編譯為目標文件

    使用以下命令編譯源文件為目標文件:

    g++ -c example.cpp -o example.o
    

    3.創建動態庫

    使用 -shared 標志將目標文件鏈接為動態庫。

    g++ -shared -o example.dll example.o
    

    生成的動態庫文件 example.dll 可以在程序中使用。

使用動態鏈接庫
在 Linux 上使用動態鏈接庫
  1. 編寫使用庫的代碼

    創建一個C++源文件,包含對動態庫中函數的調用。

    // main.cpp
    extern void hello();int main() {hello();return 0;
    }
    

    2.編譯和鏈接

    編譯時需要指定庫的路徑和名稱,使用 -L-l 標志。

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

????????

其中,-L. 指定庫路徑為當前目錄,-lexample 指定庫名稱(lib前綴和.so擴展名可以省略)。

? 3.運行可執行文件

在運行時,操作系統需要知道動態庫的路徑。可以使用LD_LIBRARY_PATH環境變量指定庫路徑。

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./main

在 Windows 上使用動態鏈接庫
  1. 編寫使用庫的代碼

    Windows上的代碼編寫與Linux相似,但需要使用__declspec(dllimport)指令來標識導入的函數。

    // main.cpp
    __declspec(dllimport) void hello();int main() {hello();return 0;
    }
    

    2.編譯和鏈接

    在編譯時,需要指定庫的路徑和名稱。

    g++ main.cpp example.dll -o main
    

    3.運行可執行文件

    確保動態庫文件(example.dll)在可執行文件的同一目錄或系統的PATH環境變量中指定的目錄。

    ./main.exe
    

總結

  • 鏈接器 的主要任務是將多個目標文件和庫文件合并,解析符號,重定位地址,最終生成一個可執行文件。
  • 靜態鏈接 將庫代碼嵌入到可執行文件中,生成的可執行文件獨立,但體積較大且更新麻煩。
  • 動態鏈接 在運行時加載庫文件,使可執行文件體積更小,更新更靈活,但需要在運行時正確找到庫文件。
  • 創建和使用動態鏈接庫涉及編譯源代碼為目標文件、生成動態庫、以及在編譯和運行時正確指定庫的路徑。

?

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

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

相關文章

20240704每日后端------聊聊 mybatis的 where 1=1

目標 最近&#xff0c;在項目中使用MyBatis進行SQL腳本編寫時&#xff0c;我遇到了以“WHERE 11”開頭的WHERE子句的做法&#xff0c;以簡化多個條件的串聯。這里有一個例子來討論這種技術以及“WHERE 11”是否對性能有任何影響。 <select id"" parameterType&q…

【數據結構】09.樹與二叉樹

一、樹的概念與結構 1.1 樹的概念 樹是一種非線性的數據結構&#xff0c;它是由n&#xff08;n>0&#xff09;個有限結點組成一個具有層次關系的集合。把它叫做樹是因為它看起來像一棵倒掛的樹&#xff0c;也就是說它是根朝上&#xff0c;而葉朝下的。 根結點&#xff1a;根…

04采訪:數字人直播

?AI技術的迭代對數字人直播一定是有正向推動作用的。直播可持續性差,投入產出極不協調。不適合前期大量投入。直播現在這個東西有一個問題,因為直播開始帶貨了,就已經不是一個單純的娛樂性質的視頻內容,而是對帶有一種商業目的內容。 直播帶貨的痛點:對主播而言是觀眾;…

俯臥撐計數器(Python)

通過 MediaPipe 檢測人體姿態&#xff0c;計算俯臥撐角度和計數&#xff0c;并在圖像上進行可視化展示 需要有cv2庫和mediapipe庫 mediapipe庫&#xff1a; MediaPipe是Google開源的機器學習框架&#xff0c;用于構建實時音頻、視頻和多媒體處理應用程序。它提供了一組預訓練的…

一文清晰了解HTML

有這樣一個txt記事本文件和一張圖片&#xff1a; txt文本內容是這樣的&#xff1a; <html><head><title>HTML學習</title></head><body><h1>hello HTML</h1><img src"高清修復.png"/></body> </html…

LabVIEW的JKI State Machine

JKI State Machine是一種廣泛使用的LabVIEW架構&#xff0c;由JKI公司開發。這種狀態機架構在LabVIEW中提供了靈活、可擴展和高效的編程模式&#xff0c;適用于各種復雜的應用場景。JKI State Machine通過狀態的定義和切換&#xff0c;實現了程序邏輯的清晰組織和管理&#xff…

VSCode工程中task.json的作用

在 Visual Studio Code&#xff08;VSCode&#xff09;中&#xff0c;tasks.json 文件是用來定義和配置任務&#xff08;Tasks&#xff09;的。任務指的是在開發過程中需要自動化執行的一系列操作&#xff0c;例如編譯代碼、運行測試、打包項目等。通過配置 tasks.json&#xf…

In Search of Lost Online Test-time Adaptation: A Survey--論文筆記

論文筆記 資料 1.代碼地址 https://github.com/jo-wang/otta_vit_survey 2.論文地址 https://arxiv.org/abs/2310.20199 3.數據集地址 1論文摘要的翻譯 本文介紹了在線測試時間適應(online test-time adaptation,OTTA)的全面調查&#xff0c;OTTA是一種專注于使機器學習…

【軟件分享】我們都需要會用的ArcGIS10.8和ArcGIS Pro

ArcGIS是地理人必備的地理制圖、空間分析常用的工具&#xff0c;讀地理&#xff0c;或多或少都會接觸到ArcGIS的使用&#xff0c;今天小編要帶來的就是ArcGIS10.8軟件資源和升級版ArcGIS Pro的軟件資源。 軟件安裝包獲取 公眾號回復關鍵詞&#xff1a;“ArcGIS"&#xff…

*算法訓練(leetcode)第二十五天 | 134. 加油站、135. 分發糖果、860. 檸檬水找零、406. 根據身高重建隊列

刷題記錄 134. 加油站135. 分發糖果860. 檸檬水找零406. 根據身高重建隊列 134. 加油站 leetcode題目地址 記錄全局剩余油量和當前剩余油量&#xff0c;當前剩余小于0時&#xff0c;其實位置是當前位置的后一個位置。若全局剩余油量為負&#xff0c;則說明整體油量不足以走完…

防爆手機終端安全管理平臺

防爆手機終端安全管理平臺能夠滿足國家能源、化工企業對安全生產信息化運行需求&#xff0c;能夠快速搭建起高效、快捷的移動終端管理平臺&#xff0c;提高企業安全生產管理水平&#xff0c;保證企業的安全運行和可持續發展。#防爆手機 #終端安全 #移動安全 能源、化工等生產單…

公有鏈、私有鏈與聯盟鏈:區塊鏈技術的多元化應用與比較

引言 區塊鏈技術自2008年比特幣白皮書發布以來&#xff0c;迅速發展成為一項具有顛覆性潛力的技術。區塊鏈通過去中心化、不可篡改和透明的方式&#xff0c;提供了一種全新的數據存儲和管理方式。起初&#xff0c;區塊鏈主要應用于加密貨幣&#xff0c;如比特幣和以太坊。然而&…

SQL Server 設置端口詳解

前言 在數據庫管理和開發過程中&#xff0c;SQL Server是一個廣泛使用的關系型數據庫管理系統。默認情況下&#xff0c;SQL Server使用1433端口進行通信。然而&#xff0c;出于安全性、端口沖突或網絡限制等原因&#xff0c;我們有時需要更改SQL Server的默認端口。本文將詳細…

VBA-計時器的數據進行整理

對計時器的數據進行整理 需求原始數據程序步驟VBA程序結果 需求 需要在txt文件中提取出分和秒分別在兩列 原始數據 數據結構 計次7 00:01.855 計次6 00:09.028 計次5 00:08.586 計次4 00:08.865 計次3 00:07.371 計次2 00:06.192 計次1 00:05.949 程序步驟 1、利用Trim()去…

易備數據備份軟件——低成本、高效能、全方位地守護您的數據安全

在數字化的時代&#xff0c;數據是企業和個人最寶貴的資產。然而&#xff0c;數據丟失、系統故障、惡意攻擊等威脅時刻存在。如何確保數據的安全與完整&#xff1f;易備數據備份軟件為您提供全方位無死角的解決方案&#xff0c;讓您高枕無憂&#xff01; 云備份&#xff1a;暢…

CV每日論文--2024.7.4

1、InternLM-XComposer-2.5: A Versatile Large Vision Language Model Supporting Long-Contextual Input and Output 中文標題&#xff1a;InternLM-XComposer-2.5&#xff1a;支持長上下文輸入和輸出的多功能大視覺語言模型 簡介&#xff1a;我們推出了InternLM-XComposer-…

079、類的繼承

繼承是對已有的類進行擴展創建出新的類&#xff0c;這個過程就叫做繼承。其中&#xff0c;提供繼承信息的類叫做父類&#xff08;超類、基類&#xff09;&#xff0c;得到繼承信息的類稱為子類&#xff08;派生類&#xff09;。 基本語法 繼承是通過在類定義語句中使用圓括號…

控制周期與控制頻率

控制周期是指控制系統中執行一次完整控制循環所需的時間間隔。它表示了控制系統對輸入信號進行處理、執行控制算法、生成輸出信號并更新系統狀態的頻率。在實時控制系統中&#xff0c;控制周期的選擇對系統的性能和穩定性具有重要影響。較短的控制周期可以提高系統的響應速度&a…

高級java每日一道面試題-2024年7月8日

文章目錄 面試官問: final 在java中有什么作用面試者回答:1. final修飾變量基本數據類型&#xff1a;示例&#xff1a; 對象引用&#xff1a;示例&#xff1a; 2. final修飾方法示例&#xff1a; 3. final修飾類示例&#xff1a; 4. final局部變量和參數示例&#xff1a; 總結 …

互聯網十萬個為什么之什么是CDN?

CDN&#xff08;Content Delivery Network&#xff0c;內容分發網絡&#xff09;是一組分布在不同地理位置的服務器&#xff0c;其目的是更有效地向用戶分發互聯網內容。通過緩存內容&#xff08;如網頁、圖片、視頻和其他類型的網絡數據&#xff09;在多個服務器上&#xff0c…