www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > > 嵌入式悅翔園
[導(dǎo)讀]學(xué)習(xí)Linux動態(tài)鏈接庫是一個繞不開的話題,我們今天就一起來看一下什么是動態(tài)鏈接庫、動態(tài)鏈接庫有什么好處、如何編譯出一個動態(tài)鏈接庫等幾個關(guān)于動態(tài)鏈接庫的幾個基本概念,廢話少說咱們直接開始

前言

學(xué)習(xí)Linux動態(tài)鏈接庫是一個繞不開的話題,我們今天就一起來看一下什么是動態(tài)鏈接庫、動態(tài)鏈接庫有什么好處、如何編譯出一個動態(tài)鏈接庫等幾個關(guān)于動態(tài)鏈接庫的幾個基本概念,廢話少說咱們直接開始!

鏈接庫是什么?

當(dāng)使用 C 編程語言編寫一個應(yīng)用程序時,我們不可能每個程序都從最底層開始編寫,這樣的話無論是學(xué)習(xí)還是工作,都會帶來很多的不便,于是庫就出現(xiàn)了。

我們可以把庫理解成前輩給我們寫好的可以直接拿來用的、成熟的代碼。本質(zhì)上來所庫是一種可執(zhí)行的二進(jìn)制文件,可以直接被操作系統(tǒng)載入內(nèi)存執(zhí)行,庫有兩種:靜態(tài)庫(.a、.lib)和動態(tài)庫(.so、.dll)。

你的代碼通常有多個庫文件,庫文件是計算機中給我們提供的一類函數(shù)、變量或類,我們無需知道他們是具體是怎么實現(xiàn)的,我們只需要關(guān)心它是怎么使用的,比如需要哪些參數(shù)、實現(xiàn)什么功能、返回值是什么樣的等等。

本質(zhì)上來說庫是一種可執(zhí)行代碼的二進(jìn)制形式,可以被操作系統(tǒng)載入內(nèi)存執(zhí)行。

在這里插入圖片描述

靜態(tài)鏈接庫

靜態(tài)鏈接庫是指編譯鏈接時,把庫文件的代碼全部加入到可執(zhí)行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了。其后綴名一般為 .a。

我們需要注意的是靜態(tài)庫是會隨著編譯一起被編譯到 .o文件中的,即一旦程序編譯靜態(tài)庫與匯編生成的目標(biāo)文件一起鏈接為可執(zhí)行文件,那么靜態(tài)庫必定跟.o文件格式相似,只有這樣才能和目標(biāo)文件成功鏈接。

靜態(tài)鏈接庫的特點

  • 靜態(tài)庫對函數(shù)庫的鏈接是放在編譯時期完成的。

  • 程序在運行時與函數(shù)庫再無瓜葛,移植方便。

  • 浪費空間和資源,因為所有相關(guān)的目標(biāo)文件與牽涉到的函數(shù)庫被鏈接合成一個可執(zhí)行文件。

動態(tài)鏈接庫

通過上面對靜態(tài)鏈接庫的介紹我們其實對庫應(yīng)該已經(jīng)有個概念了,既然有靜態(tài)鏈接庫那肯定就存在動態(tài)的鏈接庫,那什么是動態(tài)鏈接庫呢?我們一起來看一下!

我們知道靜態(tài)鏈接庫會占用很多不必要的資源,那我們就能想到動態(tài)鏈接庫的第一個特點肯定就是節(jié)省資源。

動態(tài)庫在程序編譯時并不會像靜態(tài)鏈接庫那樣被連接到目標(biāo)代碼中,而是在程序運行是才被載入。不同的應(yīng)用程序如果調(diào)用相同的庫,那么在內(nèi)存里只需要有一份該共享庫的實例,規(guī)避了空間浪費問題。動態(tài)庫在程序運行是才被載入,也解決了靜態(tài)庫對程序的更新、部署和發(fā)布頁會帶來麻煩。用戶只需要更新動態(tài)庫即可,增量更新。

動態(tài)庫一般后綴名為 .so,gcc/g++在編譯時默認(rèn)使用動態(tài)庫。無論靜態(tài)庫,還是動態(tài)庫,都是由 .o文件創(chuàng)建的。

動態(tài)庫的編譯

下面通過一個例子來介紹如何生成一個動態(tài)庫。建一個頭文件:dynamic.h三個.cpp文件:dynamic_a.cpp、dynamic_b.cpp, dynamic_c.cpp我們將這幾個文件編譯成一個動態(tài)庫:libdynamic.so。

dynamic.h

#ifndef __DYNAMIC_H_ #define __DYNAMIC_H_ #include  void dynamic_a(); void dynamic_b(); void dynamic_c(); #endif 

dynamic_a.cpp

#include"dynamic.h" void dynamic_a() { cout<<"this is in dynamic_a "<<endl;
}

dynamic_b.cpp

#include"dynamic.h" void dynamic_b() { cout<<"this is in dynamic_b "<<endl;
}

dynamic_c.cpp

#include"dynamic.h" void dynamic_c() { cout<<"this is in dynamic_c "<<endl;
}

將這幾個文件編譯成動態(tài)庫libdynamic.so。編譯命令如下:

g++ dynamic_a.cpp dynamic_b.cpp dynamic_c.cpp -fPIC -shared -o libdynamic.so

參數(shù)說明:-shared:該選項指定生成動態(tài)連接庫-fPIC:表示編譯為位置獨立的代碼,不用此選項的話編譯后的代碼是位置相關(guān)的,所以動態(tài)載入時是通過代碼拷貝的方式來滿足不同進(jìn)程的需要,而不能達(dá)到真正代碼段共享的目的。

在上面的部分,我們已經(jīng)生成了一個libdynamic.so的動態(tài)鏈接庫,現(xiàn)在我們用一個程序來調(diào)用這個動態(tài)鏈接庫。

main.cpp

#include"dynamic.h" int main() {
  dynamic_c();
  dynamic_c();
  dynamic_c(); return 0;
}

main.cpp與libdynamic.so鏈接成一個可執(zhí)行文件main,命令如下:

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

參數(shù)說明:-L:表示要連接的庫在當(dāng)前目錄中-ldynamic:編譯器查找動態(tài)連接庫時有隱含的命名規(guī)則,即在給出的名字前面加上lib,后面加上.so來確定庫的名稱。

測試可執(zhí)行程序main是否已經(jīng)鏈接的動態(tài)庫libdynamic.so,如果列出了libdynamic.so,那么就說明正常鏈接了。可以執(zhí)行以下命令:

ldd main

如果運行:

./main

出現(xiàn)錯誤:

error while loading shared libraries: libdynamic.so: cannot open shared object file: No such file or directory

錯誤原因:

ld提示找不到庫文件,而庫文件就在當(dāng)前目錄中。

鏈接器ld默認(rèn)的目錄是/lib和/usr/lib,如果放在其他路徑也可以,需要讓ld知道庫文件在哪里。

解決方法1:

編輯/etc/ld.so.conf文件,在新的一行中加入庫文件所在目錄;比如筆者應(yīng)添加:/home/neu/code/Dynamic_library

sudo ldconfig

目的是用ldconfig加載,以更新/etc/ld.so.cache文件。

靜態(tài)庫的編譯

就以以上代碼演示,最好把生成的動態(tài)庫的東西全部刪掉。

編譯靜態(tài)庫

g++ -c dynamic_a.cpp dynamic_b.cpp dynamic_c.cpp

使用ar命令創(chuàng)建靜態(tài)庫文件(把目標(biāo)文檔歸檔)

ar cr libstatic.a dynamic_a.o dynamic_b.o dynamic_c.o  //cr標(biāo)志告訴ar將object文件封裝(archive)

參數(shù)說明:

d 從指定的靜態(tài)庫文件中刪除文件 
  m 把文件移動到指定的靜態(tài)庫文件中 
  p 把靜態(tài)庫文件中指定的文件輸出到標(biāo)準(zhǔn)輸出 
  q 快速地把文件追加到靜態(tài)庫文件中 
  r 把文件插入到靜態(tài)庫文件中 
  t 顯示靜態(tài)庫文件中文件的列表 
  x 從靜態(tài)庫文件中提取文件 
  a 把新的目標(biāo)文件(*.o)添加到靜態(tài)庫文件中現(xiàn)有文件之后

使用nm -s 命令來查看.a文件的內(nèi)容

nm -s libstatic.a

鏈接靜態(tài)庫

g++ main.cpp -lstatic -L. -static -o main//這里的-static選項是告訴編譯器,hello是靜態(tài)庫也可以用 //g++ main.cpp -lstatic -L.  -o main  

執(zhí)行以下命令,因為筆者還是用的動態(tài)庫的代碼,所以結(jié)果一樣

./main

動態(tài)鏈接庫的優(yōu)點

  • 節(jié)省資源;
  • 可以實現(xiàn)進(jìn)程間資源共享;
  • 更新、部署、發(fā)布簡單;
  • 可以控制動態(tài)庫的加載時間(何時加載);

關(guān)于第二點我們該如何理解呢?進(jìn)程間的資源共享就是說,某個程序的在運行中要調(diào)用某個動態(tài)鏈接庫函數(shù)的時候,操作系統(tǒng)首先會查看所有正在運行的程序,看在內(nèi)存里是否已有此庫函數(shù)的拷貝了。如果有,則讓其共享那一個拷貝,只有沒有才鏈接載入。

這樣的模式雖然會帶來一些 “動態(tài)鏈接” 額外的開銷,卻大大的節(jié)省了系統(tǒng)的內(nèi)存資源。C的標(biāo)準(zhǔn)庫就是動態(tài)鏈接庫,也就是說系統(tǒng)中所有運行的程序共享著同一個C標(biāo)準(zhǔn)庫的代碼段。

結(jié)語

我們在編寫程序的時候,可以根據(jù)需求選擇什么時候或者什么情況下,鏈接載入哪個動態(tài)鏈接庫函數(shù)。你可以有一個相當(dāng)大的軟件,但每次運行的時候,由于不同的操作需求,只有一小部分程序被載入內(nèi)存。

所有的函數(shù)本著 “有需求才調(diào)入” 的原則,于是大大節(jié)省了系統(tǒng)資源。比如現(xiàn)在的軟件通常都能打開若干種不同類型的文件,這些讀寫操作通常都用動態(tài)鏈接庫來實現(xiàn)。

在一次運行當(dāng)中,一般只有一種類型的文件將會被打開。所以直到程序知道文件的類型以后再載入相應(yīng)的讀寫函數(shù),而不是一開始就將所有的讀寫函數(shù)都載入,然后才發(fā)覺在整個程序中根本沒有用到它們。

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

CPU親和度通過限制進(jìn)程或線程可以運行的CPU核心集合,使得它們只能在指定的CPU核心上執(zhí)行。這可以減少CPU緩存的失效次數(shù),提高緩存命中率,從而提升系統(tǒng)性能。

關(guān)鍵字: Linux 嵌入式

在Linux系統(tǒng)性能優(yōu)化中,內(nèi)存管理與網(wǎng)絡(luò)連接處理是兩大核心領(lǐng)域。vm.swappiness與net.core.somaxconn作為關(guān)鍵內(nèi)核參數(shù),直接影響系統(tǒng)在高負(fù)載場景下的穩(wěn)定性與響應(yīng)速度。本文通過實戰(zhàn)案例解析這兩個...

關(guān)鍵字: Linux 內(nèi)存管理

對于LLM,我使用b谷歌Gemini的免費層,所以唯一的成本是n8n托管。在使用了n8n Cloud的免費積分后,我決定將其托管在Railway上(5美元/月)。然而,由于n8n是開源的,您可以在自己的服務(wù)器上托管它,而...

關(guān)鍵字: 人工智能 n8n Linux

在Linux系統(tǒng)管理中,權(quán)限控制是安全運維的核心。本文通過解析/etc/sudoers文件配置與組策略的深度應(yīng)用,結(jié)合某金融企業(yè)生產(chǎn)環(huán)境案例(成功攔截98.7%的非法提權(quán)嘗試),揭示精細(xì)化權(quán)限管理的關(guān)鍵技術(shù)點,包括命令別...

關(guān)鍵字: Linux 用戶權(quán)限 sudoers文件

Linux內(nèi)核中的信號量(Semaphore)是一種用于資源管理的同步原語,它允許多個進(jìn)程或線程對共享資源進(jìn)行訪問控制。信號量的主要作用是限制對共享資源的并發(fā)訪問數(shù)量,從而防止系統(tǒng)過載和數(shù)據(jù)不一致的問題。

關(guān)鍵字: Linux 嵌入式

在云計算與容器化技術(shù)蓬勃發(fā)展的今天,Linux網(wǎng)絡(luò)命名空間(Network Namespace)已成為構(gòu)建輕量級虛擬網(wǎng)絡(luò)的核心組件。某頭部互聯(lián)網(wǎng)企業(yè)通過命名空間技術(shù)將測試環(huán)境資源消耗降低75%,故障隔離效率提升90%。本...

關(guān)鍵字: Linux 云計算

在Linux內(nèi)核4.18+和主流發(fā)行版(RHEL 8/Ubuntu 20.04+)全面轉(zhuǎn)向nftables的背景下,某電商平臺通過遷移將防火墻規(guī)則處理效率提升40%,延遲降低65%。本文基于真實生產(chǎn)環(huán)境案例,詳解從ipt...

關(guān)鍵字: nftables Linux

在Linux設(shè)備驅(qū)動開發(fā)中,等待隊列(Wait Queue)是實現(xiàn)進(jìn)程睡眠與喚醒的核心機制,它允許進(jìn)程在資源不可用時主動放棄CPU,進(jìn)入可中斷睡眠狀態(tài),待資源就緒后再被喚醒。本文通過C語言模型解析等待隊列的實現(xiàn)原理,結(jié)合...

關(guān)鍵字: 驅(qū)動開發(fā) C語言 Linux

在Unix/Linux進(jìn)程間通信中,管道(pipe)因其簡單高效被廣泛使用,但默認(rèn)的半雙工特性和無同步機制容易導(dǎo)致數(shù)據(jù)競爭。本文通過父子進(jìn)程雙向通信案例,深入分析互斥鎖與狀態(tài)機在管道同步中的應(yīng)用,實現(xiàn)100%可靠的數(shù)據(jù)傳...

關(guān)鍵字: 管道通信 父子進(jìn)程 Linux

RTOS :RTOS的核心優(yōu)勢在于其實時性。它采用搶占式調(diào)度策略,確保高優(yōu)先級任務(wù)能夠立即獲得CPU資源,從而在最短時間內(nèi)完成處理。RTOS的實時性是通過嚴(yán)格的時間管理和任務(wù)調(diào)度算法實現(xiàn)的,能夠滿足對時間敏感性要求極高的...

關(guān)鍵字: Linux RTOS
關(guān)閉