亚洲精品一二区_国产黄色片网站_99久久久成人国产精品_蜜臀网_国产精品一区二区三区免费_成人av中文字幕_91精品国产欧美一区二区成人

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > Linux下動態庫和靜態庫的制作及使用

Linux下動態庫和靜態庫的制作及使用 時間:2018-09-26      來源:未知

在實際的開發過程中,編寫程序往往都需要依賴很多基礎的底層庫,比方說平時用的較多的標準C庫,數學庫等等;我們會頻繁的使用這些庫里的函數,這些函數大多數都是前人為我們寫好的,所以值得慶幸的是我們的工作不必從零開始,我們要做的只是在恰當的位置調用合適的庫函數去實現相應的功能,充分利用前人的勞動成果,就是“站在巨人的肩膀上”。本文主要簡述Linux下庫的制作以及使用方法。

一、什么是庫

庫從本質上來說是一種可執行代碼的二進制格式,可以被載入內存中執行。根據鏈接時期的不同,庫又有:靜態庫和共享庫(動態庫)二者的不同點在于代碼被載入的時刻不同。

靜態庫的代碼在編譯過程中已經被載入可執行程序,因此體積較大。

共享庫的代碼是在可執行程序運行時才載入內存的,在編譯過程中僅簡單的引用,因此代碼體積較小。

二、初識靜態庫與動態庫

1.靜態函數庫

這類庫的名字一般是libxxx.a,xxx為庫的名字。利用靜態函數庫編譯成的文件比較大,因為整個函數庫的所有數據都會被整合進目標代碼中,他的優點就顯而易見了,即編譯后的執行程序不需要外部的函數庫支持,因為所有使用的函數都已經被編譯進去了。當然這也會成為他的缺點,因為如果靜態函數庫改變了,那么你的程序必須重新編譯。

2.動態函數庫

這類庫的名字一般是libxxx.M.N.so,同樣的xxx為庫的名字,M是庫的主版本號,N是庫的副版本號。當然也可以不要版本號,但名字必須有。相對于靜態函數庫,動態函數庫在編譯的時候并沒有被編譯進目標代碼中,你的程序執行到相關函數時才調用該函數庫里的相應函數,因此動態函數庫所產生的可執行文件比較小。由于函數庫沒有被整合進你的程序,而是程序運行時動態的申請并調用,所以程序的運行環境中必須提供相應的庫。動態函數庫的改變并不影響你的程序,所以動態函數庫的升級比較方便。linux系統有幾個重要的目錄存放相應的函數庫,如/lib /usr/lib。

三、靜態庫與動態庫的比較

靜態庫其實從某種意義上來說只不過它操作的對象是目標代碼而不是源碼而已。因為靜態庫被鏈接后庫就直接嵌入可執行文件中了,這樣就帶來了兩個問題。

(1)首先就是系統空間被浪費了。這是顯而易見的,想象一下,如果多個程序鏈接了同一個庫,則每一個生成的可執行文件就都會有一個庫的副本,必然會浪費系統空間。

(2)再者,一旦發現了庫中有bug,挽救起來就比較麻煩了。必須一一把鏈接該庫的程序找出來,然后重新編譯。

而動態庫的出現正彌補了靜態庫的以上弊端。因為動態庫是在程序運行時被鏈接的,所以磁盤上只須保留一份副本,因此節約了磁盤空間。如果發現了bug或要升級也很簡單,只要用新的庫把原來的替換掉就行了。

但是靜態庫也有自己的優點:編譯后的執行程序不需要外部的函數庫支持,因為所有使用的函數都已經被編譯進去了。

四、如何判斷一個程序有沒有鏈接動態庫

(1)file命令

file程序是用來判斷文件類型的,啥文件一看都清楚明了。

(2)ldd命令

看動態庫,如果目標程序沒有鏈接動態庫,則打印“not a dynamic executable” (不是動態可執行文件)

五、靜態庫的制作

(1) 為pr1和pr2生成object文件

gcc -O -c pr1.c pr2.c

(2) ls

(3) 鏈接靜態庫

為了在編譯程序中正確找到庫文件,靜態庫必須按照 lib[name].a 的規則命名,如下例中[name]=pr.

ar參數意義:

c: create的意思

r:在庫中插入模塊(替換)。當插入的模塊名已經在庫中存在,則替換同名的模塊。

s:寫入一個目標文件索引到庫中,或者更新一個存在的目標文件索引。

v:該選項用來顯示執行操作選項的附加信息。

t:顯示庫的模塊表清單。一般只顯示模塊名。

ar -crsv libpr.a pr1.o pr2.o

ar -t libpr.a //顯示靜態庫所依賴的文件

(4) 編譯鏈接選項

-L 及-l 參數放在后面.其中,-L 加載庫文件路徑,-l 指明庫文件名字.

gcc -o main main.c -L./ -lpr //生成main

-I后面接頭文件 (大寫的i)

-L后面接庫文件路徑路徑

-l后面接庫文件名,除了“lib”和“.a”部分,全名為libpr.a

(5)執行目標程序

./main

六、動態庫的制作

注意,和動態庫相關的路徑搜索問題可以認為分鏈接時的搜索 和 運行時加載的搜索。鏈接時的搜索就是”-L”,比較簡單直接,我們重點講的是運行時的加載搜索。

(1)生成動態庫 xxx.so

gcc -fPIC -Wall -c pr1.c

PIC告訴編譯器產生與位置無關代碼(Position-Independent Code), 則產生的代碼中,沒有絕對地址,全部使用相對地址,故而代碼可以被加載器加載到內存的任意位置,都可以正確的執行。這正是共享庫所要求的,共享庫被加載時,在內存的位置不是固定的。

gcc -shared -o libpr.so pr1.o

or use one line:

gcc -O -fPIC -shared -o libpr.so pr1.c

(2)編譯時調用動態庫

gcc -o test main.c –L. -lpr

采用該方法執行會報告./test: error while loading shared libraries: libpr.so: cannot open shared object file: No such file or directory

原因:因為在動態函數庫使用時,會查找/usr/lib、/lib目錄下的動態函數庫,而此時我們生成的庫不在里邊。

這個時候有好幾種方法可以讓他成功運行:

(1)直接簡單的方法就是把so拉到/usr/lib或/lib中去,但這好像有點污染環境吧。需要root權限,在別人的電腦上會很麻煩;會把系統目錄弄得混亂。

(2)新建并編輯/etc/ld.so.conf.d/my.conf文件,加入庫所在目錄的路徑,執行ldconfig命令更新ld.so.cache文件但是需要root權限。

(3)export LD_LIBRARY_PATH=/tmp

不過這樣export 只對當前shell有效,當另開一個shell時候,又要重新設置。可以把export LD_LIBRARY_PATH=/tmp 語句寫到 ~/.bashrc中,這樣就對當前用戶有效了,寫到/etc/bashrc中就對所有用戶有效了。

echo $LD_LIBRARY_PATH

不過LD_LIBRARY_PATH的設定作用是全局的,過多的使用可能會影響到其他應用程序的運行,所以多用在調試。

小結:

總而言之,靜態庫是以空間換時間,動態庫是以時間換空間。無論你是在Linux平臺還是Windows平臺下做開發,庫的使用都大同小異。熟練的使各種庫,會給我們帶來許多便利,減少工作的負擔加快工程的進度,從此升職,加薪不是夢,希望對你有所幫助。

上一篇:Android教學中遇到的內存泄露和內存溢出

下一篇:經典進程間通信之無名管道和有名管道

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 激情6月丁香婷婷色综合 | 人人玩人人添人人澡欧美 | 国产成人www免费人成看片 | 狂野欧美性猛交xxxx巴西 | 久草资源在线 | 日本特黄色 | 亚洲日本在线播放 | 久精品视频 | 欧美3区| 久久久精品波多野结衣 | 97人人模人人爽人人爽喊 | 人人爽人人干 | 免费日批网站 | 国产成人欧美一区二区三区的 | 国产精品五月天 | 国产午夜免费视频片夜色 | 理论片2019最新理论片免费视看 | 尹人香蕉99久久综合网站 | 国内高清久久久久久久久 | 在线观看中文字幕 | 日韩人成免费网站大片 | 亚洲日本色 | 午夜视频网址 | 男人天堂免费 | 欧美性受xxxx狂喷水 | 日本xxx网站| 经典香港一级a毛片免费看 精彩视频一区二区 | 亚洲欧美v国产一区二区 | 久久一区二区三区免费 | 日本人成年视频在线观看 | 秋霞日韩| 免费看操片| 久草免费在线 | 日本高清视频www夜色资源 | 国产欧美日韩一区二区三区视频 | 青青草免费在线观看 | 欧美国产一区二区三区 | 国产精品久久久久久久专区 | 青青操在线观看 | 久久精品午夜视频 | 国产美女久久久久久久久久久 |