Linux基礎(七):Linux 系統上的庫文件生成與使用

? ? ? ? 學過C語言我們知道,C語言有標準庫和自定義庫,這些方便了我們的實際開發,提供了已經實現好的函數接口,我們使用的時候,只需要引入頭文件即可,那具體的實現過程又是怎么樣的呢?我們又該如何實現我們自己的庫呢?這就是我們本節需要講解的。

目錄

一、什么是庫文件

二、為什么需要庫

三、靜態庫的生成與使用

3.1 自定義靜態庫的生成

3.2 自定義靜態庫的使用

3.3 將自定義的靜態庫移動到系統庫目錄下使用

3.4 靜態庫刪除后是否可以使用

四、共享庫的生成與使用

4.1 自定義共享庫的生成

4.2 自定義共享庫的使用

4.2.1? 解決辦法1

4.2.2? 解決辦法2

4.3 共享庫刪除后是否可以使用

五、靜態庫和共享庫的區別


一、什么是庫文件

? ? ? ? 庫是一組預先編譯好的方法/函數的集合。 在 64 位的系統上有些庫也可能被存儲在/usr/lib64 下。?庫有兩種,一種是靜態庫,其命令規則為 libxxx.a,一種是共享庫,其命令規則為 libxxx.so。如下圖所示:

  1. Linux系統存儲庫的頭文件(函數的聲明)一般會被存儲在 /usr/include
  2. Linux系統存儲的庫(函數的具體實現)的位置一般在:/lib 和 /usr/lib
  3. Linux系統存儲的二進制可執行程序的位置在:/bin和/usr/bin

二、為什么需要庫

? ? ? ? ?因為在引用外部方法時,不需要改動直接用就行,但給的是.c文件的話,使用要編譯鏈接,很麻煩,所以直接生成.o文件,放到庫里,使用的時候直接鏈接就好。庫的隱蔽性較好,要讓對方使用方法,但又不想讓對象知道方法是如何讓實現的,就可以用庫。當同時有靜態庫和共享庫時,優先使用共享庫。

三、靜態庫的生成與使用

? ? ? 這里展示實現自定義的靜態庫,以及如何使用,需要個3文件:add.c? max.c? foo.h,其中“foo.h”中是函數的聲明,“add.c”和“max.c” 是函數的定義/具體實現

創建一個頭文件,包含所有自定義函數的聲明,后面再使用直接引|入自己創建的頭文件即可!

3.1 自定義靜態庫的生成

第一步:先將需要生成庫文件的所有“.c“文件編譯成“.o”文件

第二步:使用 ar 命令將第一步編譯的所有”.o”文件生成靜態庫,其中:c 是創建庫 ?r 是將方法添加到庫中? ??v 顯示過程。

至此,靜態庫已經生成啦,是不是非常簡單!注意:此時生成的靜態庫在當前目錄下,并不是系統庫文件位置,我們在下面使用的時候,要用雙引號引入頭文件即:#include '' foo. h'' 。

3.2 自定義靜態庫的使用

? ? ? ?上一小節,我們講解了如何生成靜態庫,那么,我們又該如何使用呢?

靜態庫的使用也很簡單,只需要在主函數文件里面引入我們自定義的靜態庫頭文件,然后編譯鏈接的時候,指定鏈接的靜態庫即可!

第一步:需要使用靜態庫的地方引入靜態庫對應的頭文件?

第二步:編譯鏈接的時候指定鏈接庫的位置

3.3 將自定義的靜態庫移動到系統庫目錄下使用

? ? ? ? ?當我們測試完自己的庫沒有問題后,這時候便可以將自定義的靜態庫移動到Linux系統存儲的庫的位置:/lib 和 /usr/lib,移動完之后,它就成了標準庫的一部分,后續我們的使用非常簡單,在頭文件的引入使用尖括號也可以了<>,此外,編譯鏈接的時候,也不需要指定靜態庫的位置了,因為它首先回會到標準庫位置下找,此時就可以找到。

3.4 靜態庫刪除后是否可以使用

四、共享庫的生成與使用

? ? 這里展示實現自定義的共享庫,以及如何使用,需要個3文件:add.c? max.c? foo.h,其中“foo.h”中是函數的聲明,“add.c”和“max.c” 是函數的定義/具體實現

創建一個頭文件,包含所有自定義函數的聲明,后面再使用直接引|入自己創建的頭文件即可!?

?

4.1 自定義共享庫的生成

第一步:先將需要生成庫文件的所有“.c“文件編譯成“.o”文件

第二步:使用 gcc 命令將第一步編譯的所有”.o”文件生成共享庫?

? ? ? ?在共享庫的創建過程中, -fPIC是一個編譯選項,用于生成位置無關的代碼。它告訴編譯器生成與位置無關的代碼,這對于共享庫特別重要。共享庫(也稱為動態鏈接庫)是一種在多個程序之間共享的庫。當程序加載時,操作系統會將共享庫映射到進程的地址空間中,以便程序可以調用庫中的函數和訪問庫中的變量。位置無關的代碼是一種在不同內存位置上執行時都能正常工作的代碼。這對于共享庫尤其重要,因為它們可能會在不同的內存地址空間中加載。-fPIC 選項使得編譯器生成的代碼能夠在內存中的任何位置執行,而不受具體加載地址的限制。它通常用于創建共享庫,以確保庫能夠在不同的進程中重定位到不同的內存地址,而不會發生沖突或錯誤。

至此,共享庫已經生成啦,是不是非常簡單!注意:此時生成的共享庫在當前目錄下,并不是系統庫文件位置,我們在下面使用的時候,要用雙引號引入頭文件即:#include '' foo. h'' 。

4.2 自定義共享庫的使用

? ? ? ?上一小節,我們講解了如何生成共享庫,那么,我們又該如何使用呢?

? ? ?共享庫該如何使用呢?我們先學習下靜態庫的使用,然后觀察是否可以使用,在主函數文件里面引入我們自定義的共享庫頭文件,然后編譯鏈接的時候,指定鏈接的共享庫的位置和庫名。

第一步:需要使用靜態庫的地方引入靜態庫對應的頭文件?

第二步:編譯鏈接的時候指定鏈接庫的位置??

? ? ? ? 以下是使用共享庫“libfoo.so”和“main.c”生成可執行文件的過程,其中 -L 指定庫的 存儲路徑, -l 指定庫的名稱(不需要前面的‘lib’和擴展名‘.so’), 如果在庫的存儲路徑有同名的共享庫和靜態庫,gcc 默認使用共享庫。

與靜態庫的使用對比,為什么這里會出現問題呢?又該如何解決呢?

這是因為:靜態庫和共享庫在加載庫時的行為是不同的
? ? ? ?1.靜態庫:靜態庫在鏈接時會被整體地復制到可執行文件中,因此可執行文件本身包含了靜態庫的代碼和數據。當程序運行時,靜態庫的代碼和數據已經被包含在可執行文件中,因此程序會直接調用其中的函數或訪問其中的變量,而不需要額外加載庫文件。因此,靜態庫在運行時不會去查找庫文件,而是直接使用可執行文件中已經包含的庫代碼和數據。

? ? ? ? ?2.共享庫:共享庫在程序運行時才會被加載到內存中。程序在啟動時會查找共享庫,并將其加載到內存中的地址空間。通常,操作系統會預定義一些標準位置用于查找共享庫,比去存儲庫的標準位置(/lib 或/usr/lib 等)加載。程序在運行時會根據操作系統的規則去這些標準位置下查找共享庫。如果共享庫不存在于這些位置,那么程序可能會因為找不到庫而報錯。
? ? ? ?總的來說,靜態庫在鏈接時就已經被包含在可執行文件中,程序運行時不需要額外查找庫文件;而共享庫在運行時才會被加載到內存中,程序會按照操作系統的規則去標準位置下查找共享庫。

4.2.1? 解決辦法1

既然,共享庫會去標準位置下找對應的庫,那我們就可以將共享庫移動到標準庫位置下,這樣就不會報錯了。

4.2.2? 解決辦法2

如果庫不在標準位置下,我們放在當前位置下,也可以通過設置環境變量”LD_LIBRARY_PATH”來指定加載庫的路徑,這樣也就不會報錯了。

ldd命令可以查看當前可執行程序依賴哪些庫?

4.3 共享庫刪除后是否可以使用

? ? ? ?共享庫只有在運行的時候,才會去標準庫位置下去找對應的庫,不會進行拷貝,因此刪除后,可執行程序無法運行,共享庫只有一份,靜態庫會被拷貝到可執行程序里面,因此刪除后還可以使用。

五、靜態庫和共享庫的區別

? ? ? ? 靜態庫在鏈接時將用到的方法包含到最終生成的可執行程序中,成為可執行程序的一部分,而共享庫不包含,也就是說可執行程序里面是沒有實現的方法的,只做標記,在運行程序時,才動態加載。

靜態庫:

? ? ? ?用靜態庫編譯出來的程序,相當于是把靜態庫里的.o文件拷貝了一份到可執行程序里,因此即使將庫里的文件刪除,可執行程序依然能執行。如果庫里的數據需要更新,但原來庫里的.o文件已經成為了可執行程序的一部分,此時要用更新的方法,就要把可執行程序刪除,重新編譯鏈接一個新文件。因此,靜態庫刪除后,可執行程序仍然可以正常使用

共享庫:

? ? ? ?用共享庫編譯出來的程序,相當于是標記了所需方法,但可執行程序里沒有所需方法的實現,因此當所需方法在庫里刪除后,可執行程序找不到所需方法,文件就運行不了。

共享庫里的數據更新,可執行程序,在運行時直接尋找共享庫,就直接能用更新后的.o文件。因此,共享庫刪除后,可執行程序無法正常使用!

以上就是全部內容!請務必掌握,這是后續學習的基礎,歡迎大家點贊加關注評論,您的支持是我前進最大的動力!下期再見!

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

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

相關文章

JS實現照片預覽

以下是一個簡單的JS代碼示例&#xff0c;用于實現照片預覽功能&#xff1a; <!DOCTYPE html> <html> <head><title>Photo Preview</title><script>function previewPhoto(event) {var reader new FileReader();reader.onload function(…

MySQL字符數據查詢拆分

MySQL字符數據查詢拆分 問題描述 數據表中某字段為特定單詞組字符串&#xff0c;特定字符分隔。 現有需求&#xff1a;在不影響原始數據的情況下&#xff0c;查詢顯示拆分后的單詞&#xff0c;方便后續對其進行后續操作。 演示 演示數據源 -- 測試表結構create table word_…

Java中創建不可變對象實現細節和例子

當我們在Java中創建不可變對象時&#xff0c;我們需要確保對象的狀態在創建之后不能被修改。以下是一些具體的實現細節和例子&#xff0c;展示了如何在Java中創建不可變對象。 實現細節 使用final關鍵字&#xff1a; 類定義前使用final關鍵字&#xff0c;表示該類不能被繼承&…

Mysql中的慢查詢

Mysql慢查詢的一些sql命令 慢查詢的默認事件為10秒 #注意&#xff1a;慢查詢一般是在調試階段開啟的&#xff0c;在開發階段中一般不會開啟&#xff0c;會對效率產生延誤 #查詢慢查詢是否開啟 show variables like %general%; #慢查詢時間設置 show variables like long_query…

【運維項目經歷|018】:Elasticsearch智能數據分析平臺項目

目錄 項目名稱 項目背景 項目目標 項目成果 我的角色與職責 我主要完成的工作內容 本次項目涉及的技術 本次項目遇到的問題與解決方法 本次項目中可能被面試官問到的問題 問題1&#xff1a;本次項目周期&#xff1f; 問題2&#xff1a;服務部署架構方式及數量和配置&…

【簡明指南:Python中的異常處理與穩健代碼設計】

文章目錄 前言異常處理基礎捕獲多種異常確保資源被釋放使用else子句自定義異常結論 前言 軟件開發過程中&#xff0c;保證代碼的穩健性和可靠性至關重要。異常處理是實現這一目標的關鍵技術之一。在Python編程中&#xff0c;合理地捕獲和處理異常不僅能提高程序的健壯性&#…

查找專利渠道

官方渠道 常規檢索 (cnipa.gov.cn)https://pss-system.cponline.cnipa.gov.cn/conventionalSearch 佰騰網 佰騰網 - 查專利就上佰騰網_佰騰全球專利搜索平臺_商標查詢平臺_企業工商信息查詢平臺 (baiten.cn)https://www.baiten.cn/

NLP(19)--大模型發展(3)

前言 僅記錄學習過程&#xff0c;有問題歡迎討論 大模型訓練相關知識&#xff1a; 問題&#xff1a; 數據集過大&#xff0c;快速訓練模型過大&#xff0c;gpu跑不完 方案&#xff1a; 數據并行訓練&#xff1a; 復制數據&#xff08;batch_size&#xff09;到多個gpu&…

簡述vue-router的動態路由

動態路由 addRoute 是 Vue Router 中的一個功能&#xff0c;它允許你在運行時動態地向路由表添加路由規則。這在一些需要基于用戶行為或異步數據加載路由的場景中非常有用。以下是對 addRoute 功能的詳細解釋和使用示例&#xff1a; 1. 動態路由的概念 動態路由是指在應用運行…

[雜項]優化AMD顯卡對DX9游戲(天諭)的支持

目錄 關鍵詞平臺說明背景RDNA 1、2、3 架構的顯卡支持游戲一、 優化方法1.1 下載 二、 舉個栗子&#xff08;以《天諭》為例&#xff09;2.1 下載微星 afterburner 軟件 查看游戲內信息&#xff08;可跳過&#xff09;2.2 查看D3D9 幀數2.3 關閉游戲&#xff0c;替換 dll 文件2…

精品PPT | MES設計與實踐,業務+架構+實施(免費下載))

【1】關注本公眾號&#xff0c;轉發當前文章到微信朋友圈 【2】私信發送 MES設計與實踐 【3】獲取本方案PDF下載鏈接&#xff0c;直接下載即可。 如需下載本方案PPT/WORD原格式&#xff0c;請加入微信掃描以下方案驛站知識星球&#xff0c;獲取上萬份PPT/WORD解決方案&#x…

linux的chmod的數字太難記了,用u, g, o, a更簡單!

u, g, o, 和 a是用來設置或查看文件或目錄權限在類Unix或Linux系統中的特殊字符&#xff0c;它們分別代表文件或目錄的所有者(user)、所屬組(group)、其他用戶(others)和所有用戶(all users)。 而權限方r和w是其中的兩種&#xff0c;分別代表讀權限&#xff08;read&#xff0…

【探索數據結構】線性表之單鏈表

&#x1f389;&#x1f389;&#x1f389;歡迎蒞臨我的博客空間&#xff0c;我是池央&#xff0c;一個對C和數據結構懷有無限熱忱的探索者。&#x1f64c; &#x1f338;&#x1f338;&#x1f338;這里是我分享C/C編程、數據結構應用的樂園? &#x1f388;&#x1f388;&…

Autodl服務器中Faster-rcnn(jwyang)復現(一)

前言 在做實驗時需要用到faster-rcnn做對比,本節首先完成代碼復現,用的數據集是VOC2007~ 項目地址:https://github.com/jwyang/faster-rcnn.pytorch/tree/pytorch-1.0 復現環境:autodl服務器+python3.6+cuda11.3+Ubuntu20.04+Pytorch1.10.0 目錄 一、環境配置二、編譯cud…

2024年軟考總結 信息系統管理師

選擇題 英文題&#xff0c;我是一題也沒把握&#xff0c;雖然我理解意思。 千萬不要認為考死記硬背不對。目的不在于這。工程項目中有很多重要的數字&#xff0c;能記住說明你合格。 案例 幾乎把答案全寫在案例中了。 計算題 今年最簡單。沒有考成本。 只考了關鍵路徑&a…

頭歌OpenGauss數據庫-I.復雜查詢第8關:兩門及以上課程不及格的學生

任務描述 本關任務:根據提供的表和數據,查詢兩門及其以上不及格課程的同學的學號(s_id)、姓名(s_name)及其平均成績(avg_score),要求計算平均成績后為整數。 student表數據: s_ids_names_sex01Mia女02Riley男03Aria女04Lucas女05Oliver男06Caden男07Lily女08Jacob男c…

安卓開發:相機水印設置

1.更新水印 DecimalFormat DF new DecimalFormat("#"); DecimalFormat DF1 new DecimalFormat("#.#");LocationManager LM (LocationManager)getSystemService(Context.LOCATION_SERVICE); LM.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2…

【學習筆記】計算機組成原理(七)

指令系統 文章目錄 指令系統7.1 機器指令7.1.1 指令的一般格式7.1.2 指令字長 7.2 操作數類型和操作類型7.2.1 操作數類型7.2.2 數據在存儲器中的存放方式7.2.3 操作類型 7.3 尋址方式7.3.1 指令尋址7.3.1.1 順序尋址7.3.1.2 跳躍尋址 7.3.2 數據尋址7.3.2.1 立即尋址7.3.2.2 直…

第四十五天 | 322.零錢兌換

題目&#xff1a;322.零錢兌換 嘗試解答&#xff1a; 1.確定dp[j]含義&#xff1a;裝滿容量為j的背包所需要放的硬幣個數為dp[j]; 2.動態轉移方程&#xff1a;dp[j] dp[j - coins[i]] 1; 3.遍歷順序&#xff1a;本題應該為組合類題目&#xff0c;不考慮裝入的順序&#x…

精品PPT | 精益生產管理中MES系統的實現與應用(免費下載)

【1】關注本公眾號&#xff0c;轉發當前文章到微信朋友圈 【2】私信發送 MES系統的實現與應用 【3】獲取本方案PDF下載鏈接&#xff0c;直接下載即可。 如需下載本方案PPT/WORD原格式&#xff0c;請加入微信掃描以下方案驛站知識星球&#xff0c;獲取上萬份PPT/WORD解決方案&…