一. 什么是庫(kù)
庫(kù)是一個(gè)二進(jìn)制文件,包含的代碼可被程序調(diào)用。例如標(biāo)準(zhǔn)C庫(kù)、數(shù)學(xué)庫(kù)、線程庫(kù)等等。庫(kù)有源碼,可下載后編譯,也可以直接安裝二進(jìn)制包。 庫(kù)是事先編譯好的,可以復(fù)用的代碼,在OS上運(yùn)行的程序基本上都要使用庫(kù)。使用庫(kù)可以提高開(kāi)發(fā)效率。Windows和Linux下庫(kù)文件的格式不兼容。Linux下包含靜態(tài)庫(kù)和共享庫(kù)。
二. 靜態(tài)庫(kù)
靜態(tài)庫(kù)有如下特點(diǎn)
編譯(鏈接)時(shí)把靜態(tài)庫(kù)中相關(guān)代碼復(fù)制到可執(zhí)行文件中
程序中包含代碼,運(yùn)行時(shí)不再需要靜態(tài)庫(kù)
程序運(yùn)行時(shí)無(wú)需加載庫(kù),運(yùn)行速度更快
占用更多磁盤(pán)和空間
靜態(tài)庫(kù)升級(jí)后,程序需要重新編譯鏈接
靜態(tài)庫(kù)的創(chuàng)建與鏈接參考如下步驟: 第一步:確定庫(kù)中函數(shù)的功能、接口
第二步:編寫(xiě)庫(kù)源碼
/****hello.c****/ #include#include"hello.h" voidhello(void){ printf("helloAndyxi "); }
/****hello.h****/ #ifndef_HELLO_H_ #define_HELLO_H_ voidhello(void); #endif
第三步:編譯生成目標(biāo)文件
linux@linux:~/andy/lib$ls hello.chello.h linux@linux:~/andy/lib$gcc-chello.c-Wall linux@linux:~/andy/lib$ls hello.chello.hhello.o
第四步:創(chuàng)建靜態(tài)庫(kù)
linux@linux:~/andy/lib$ls hello.chello.hhello.o linux@linux:~/andy/lib$arcrslibhello.ahello.o//使用arcrs命令創(chuàng)建靜態(tài)庫(kù) linux@linux:~/andy/lib$ls hello.chello.hhello.olibhello.a //注意libhello.a是庫(kù)文件名,hello是庫(kù)名 linux@linux:~/andy/lib$nmlibhello.a //使用nm命令可查看庫(kù)中符號(hào)信息 hello.o: 00000000Thello Uputs
第五步:編寫(xiě)應(yīng)用程序
/****test.c****/ #include#include"hello.h" intmain(intargc,constchar*argv[]){ hello(); return0; }
第六步:編譯應(yīng)用程序并鏈接靜態(tài)庫(kù)
linux@linux:~/andy/lib$ls hello.chello.hhello.olibhello.atest.c linux@linux:~/andy/lib$gcc-otesttest.c-L.-l hello //使用-L.-l+庫(kù)名鏈接靜態(tài)庫(kù) linux@linux:~/andy/lib$ls hello.chello.hhello.olibhello.atesttest.c linux@linux:~/andy/lib$./test helloAndyxi
由于使用的是靜態(tài)庫(kù),編譯后相關(guān)代碼已經(jīng)復(fù)制到可執(zhí)行文件中。刪除靜態(tài)庫(kù),不影響程序執(zhí)行
linux@linux:~/andy/lib$ls hello.chello.hhello.olibhello.atesttest.c linux@linux:~/andy/lib$rmlibhello.a linux@linux:~/andy/lib$ls hello.chello.hhello.otesttest.c linux@linux:~/andy/lib$./test helloAndyxi
三. 共享庫(kù)
共享庫(kù)有如下特點(diǎn):
編譯(鏈接)時(shí)僅記錄用到哪個(gè)共享庫(kù)中的哪個(gè)符號(hào),不復(fù)制共享庫(kù)中相關(guān)代碼
程序不包含庫(kù)中代碼,尺寸小
多個(gè)程序可共享一個(gè)庫(kù)
程序運(yùn)行時(shí)需要加載庫(kù)
庫(kù)升級(jí)方便,無(wú)需重新編譯程序
使用更加廣泛
共享庫(kù)的創(chuàng)建與鏈接參考如下步驟: 第一步:確定庫(kù)中函數(shù)的功能、接口
第二步:編寫(xiě)庫(kù)源碼
/****hello.c****/ #includevoidhello(void){ printf("helloworld "); return; }
/****bye.c****/ #includevoidbye(void){ printf("bye! "); return; }
/****共享庫(kù)頭文件common.h****/ #ifndef__COMMON_H__ #define__COMMON_H__ voidhello(void); voidbye(void); #endif
第三步:編譯生成目標(biāo)文件
linux@linux:~/andy/lib/share$ls bye.ccommon.hhello.c linux@linux:~/andy/lib/share$gcc-c-fPIC*.c-Wall linux@linux:~/andy/lib/share$ls bye.cbye.ocommon.hhello.chello.o
fPIC選項(xiàng):告訴編譯器生成位置無(wú)關(guān)代碼
位置無(wú)關(guān)代碼:生成的".o文件"文件中的代碼可以被加載到任意的地址執(zhí)行。編譯時(shí)用到了相對(duì)尋址而不是絕對(duì)尋址
第四步:創(chuàng)建共享庫(kù)common
linux@linux:~/andy/lib/share$gcc-shared-olibcommon.so.1hello.obye.o linux@linux:~/andy/lib/share$ls bye.cbye.ocommon.hhello.chello.olibcommon.so.1
shared選項(xiàng):告訴編譯器生成一個(gè)共享庫(kù)
生成的共享庫(kù)的文件名叫"libcommon.so.1",其中".so"表示這是一個(gè)共享庫(kù),".1"表示這個(gè)庫(kù)的版本是1
符號(hào)鏈接文件命名規(guī)則:lib<庫(kù)名>.so
第五步:編寫(xiě)應(yīng)用程序
/****test.c****/ #include#include"common.h" intmain(intargc,constchar*argv[]){ hello(); bye(); return0; }
第六步:編譯應(yīng)用程序并鏈接共享庫(kù)
#****為共享庫(kù)文件創(chuàng)建鏈接文件****# linux@linux:~/andy/lib/share$ls bye.cbye.ocommon.hhello.chello.olibcommon.so.1test.c linux@linux:~/andy/lib/share$ln-slibcommon.so.1libcommon.so //ln-s創(chuàng)建符號(hào)鏈接 linux@linux:~/andy/lib/share$ls bye.cbye.ocommon.hhello.chello.olibcommon.solibcommon.so.1test.c
#****編譯應(yīng)用程序并鏈接共享庫(kù)****# linux@linux:~/andy/lib/share$gcc-otesttest.c-L.-lcommon linux@linux-:~/andy/lib/share$ls bye.cbye.ocommon.hhello.chello.olibcommon.solibcommon.so.1testtest.c
gcc -o test test.c -L. -lcommon:可見(jiàn)此處共享庫(kù)和靜態(tài)庫(kù)用法相同;GCC在鏈接時(shí)首先找共享庫(kù),如果共享庫(kù)不存在,則鏈接靜態(tài)庫(kù),如果靜態(tài)庫(kù)也找不到,則報(bào)錯(cuò)
加"-static"選項(xiàng)后,編譯器會(huì)直接去找靜態(tài)庫(kù)
共享庫(kù)的加載:如果完成上述步驟后就執(zhí)行程序,會(huì)報(bào)如下錯(cuò)誤
linux@linux:~/andy/lib/share$./test ./test:errorwhileloadingsharedlibraries:libcommon.so:cannotopensharedobjectfile:Nosuchfileordirectory
出錯(cuò)原因:因?yàn)槌绦蜴溄拥氖枪蚕韼?kù),并沒(méi)有復(fù)制共享庫(kù)中的代碼,程序在執(zhí)行時(shí)會(huì)去加載用到的共享庫(kù),加載時(shí)會(huì)去缺省路徑(比如"/lib","/usr/lib")下尋找共享庫(kù),但是我們創(chuàng)建的庫(kù)在當(dāng)前目錄下,并不在系統(tǒng)庫(kù)的搜索路徑里,所以在執(zhí)行時(shí)找不到共享庫(kù),因此報(bào)錯(cuò)
創(chuàng)建好共享庫(kù)后還需要添加共享庫(kù)加載路徑
第七步:加載共享庫(kù)并執(zhí)行程序
linux@linux:~/andy/lib/share$exportLD_LIBRARY_PATH=$LD_LIBRARY_PATH:. linux@linux:~/andy/lib/share$./test helloworld bye!
export 用于將原來(lái)的環(huán)境變量導(dǎo)出
":"前面的"$LD_LIBRARY_PATH"是引用原先的值;":"后面的"."是追加了當(dāng)前目錄;還可追加其余共享庫(kù)的路徑,要用":"隔開(kāi)
此方法是臨時(shí)的,只對(duì)當(dāng)前終端有效。當(dāng)重新打開(kāi)一個(gè)終端再執(zhí)行改程序時(shí)又會(huì)報(bào)錯(cuò)
為了讓系統(tǒng)能找到要加載的共享庫(kù),通常由三種方法:
把庫(kù)拷貝到/usr/lib和/lib目錄下
在LD_LIBRARY_PATH環(huán)境變量中添加庫(kù)所在路徑
添加/etc/ld.so.conf.d/*.conf文件,執(zhí)行 ldconfig刷新
審核編輯:湯梓紅
-
Linux
+關(guān)注
關(guān)注
87文章
11479瀏覽量
213073 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4374瀏覽量
64425 -
靜態(tài)庫(kù)
+關(guān)注
關(guān)注
0文章
21瀏覽量
7594 -
編譯
+關(guān)注
關(guān)注
0文章
676瀏覽量
33834 -
共享庫(kù)
+關(guān)注
關(guān)注
0文章
4瀏覽量
5664
原文標(biāo)題:Linux 中的靜態(tài)庫(kù)和共享庫(kù)
文章出處:【微信號(hào):嵌入式攻城獅,微信公眾號(hào):嵌入式攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)的區(qū)別
Linux下動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)的制作及使用
Linux下靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的制作與使用
Linux系統(tǒng)共享庫(kù)編程
Linux下靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)(共享庫(kù))的制作與使用
linux靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)分析
Linux靜態(tài)元件庫(kù)資料合集免費(fèi)下載
你知道linux 靜態(tài)庫(kù)和共享庫(kù)?
講解Linux虛擬機(jī)之使用動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)

C++基礎(chǔ)語(yǔ)法知識(shí)之鏈接裝載庫(kù)中Linux 的共享庫(kù)
嵌入式Linux下動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)使用

Linux下動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)制作與調(diào)用

評(píng)論