詳解Linux動(dòng)態(tài)庫生成與使用指南
Linux下動(dòng)態(tài)庫文件的文件名形如 libxxx.so,其中so是 Shared Object 的縮寫,即可以共享的目標(biāo)文件。
在鏈接動(dòng)態(tài)庫生成可執(zhí)行文件時(shí),并不會(huì)把動(dòng)態(tài)庫的代碼復(fù)制到執(zhí)行文件中,而是在執(zhí)行文件中記錄對動(dòng)態(tài)庫的引用。
程序執(zhí)行時(shí),再去加載動(dòng)態(tài)庫文件。如果動(dòng)態(tài)庫已經(jīng)加載,則不必重復(fù)加載,從而能節(jié)省內(nèi)存空間。
Linux下生成和使用動(dòng)態(tài)庫的步驟如下:
- 編寫源文件。
- 將一個(gè)或幾個(gè)源文件編譯鏈接,生成共享庫。
- 通過 -L<path> -lxxx 的gcc選項(xiàng)鏈接生成的libxxx.so。
- 把libxxx.so放入鏈接庫的標(biāo)準(zhǔn)路徑,或指定 LD_LIBRARY_PATH,才能運(yùn)行鏈接了libxxx.so的程序。
下面通過實(shí)例詳細(xì)講解。
編寫源文件
建立一個(gè)源文件: max.c,代碼如下:
int max(int n1, int n2, int n3) { int max_num = n1; max_num = max_num < n2? n2: max_num; max_num = max_num < n3? n3: max_num; return max_num; }
編譯生成共享庫:
gcc -fPIC -shared -o libmax.so max.c
我們會(huì)得到libmax.so。
實(shí)際上上述過程分為編譯和鏈接兩步, -fPIC是編譯選項(xiàng),PIC是 Position Independent Code 的縮寫,表示要生成位置無關(guān)的代碼,這是動(dòng)態(tài)庫需要的特性; -shared是鏈接選項(xiàng),告訴gcc生成動(dòng)態(tài)庫而不是可執(zhí)行文件。
上述的一行命令等同于:
gcc -c -fPIC max.c gcc -shared -o libmax.so max.o
為動(dòng)態(tài)庫編寫接口文件
為了讓用戶知道我們的動(dòng)態(tài)庫中有哪些接口可用,我們需要編寫對應(yīng)的頭文件。
建立 max.h ,輸入以下代碼:
#ifndef __MAX_H__ #define __MAX_H__ int max(int n1, int n2, int n3); #endif
測試,鏈接動(dòng)態(tài)庫生成可執(zhí)行文件
建立一個(gè)使用max函數(shù)的test.c,代碼如下:
#include <stdio.h> #include "max.h" int main(int argc, char *argv[]) { int a = 10, b = -2, c = 100; printf("max among 10, -2 and 100 is %d.\n", max(a, b, c)); return 0; }
gcc test.c -L. -lmax 生成a.out,其中-lmax表示要鏈接libmax.so。
-L.表示搜索要鏈接的庫文件時(shí)包含當(dāng)前路徑。
注意,如果同一目錄下同時(shí)存在同名的動(dòng)態(tài)庫和靜態(tài)庫,比如 libmax.so 和 libmax.a 都在當(dāng)前路徑下,
則gcc會(huì)優(yōu)先鏈接動(dòng)態(tài)庫。
運(yùn)行
運(yùn)行 ./a.out 會(huì)得到以下的錯(cuò)誤提示。
./a.out: error while loading shared libraries: libmax.so: cannot open shared object file: No such file or directory
找不到libmax.so,原來Linux是通過 /etc/ld.so.cache 文件搜尋要鏈接的動(dòng)態(tài)庫的。
而 /etc/ld.so.cache 是 ldconfig 程序讀取 /etc/ld.so.conf 文件生成的。
(注意, /etc/ld.so.conf 中并不必包含 /lib 和 /usr/lib,ldconfig程序會(huì)自動(dòng)搜索這兩個(gè)目錄)
如果我們把 libmax.so 所在的路徑添加到 /etc/ld.so.conf 中,再以root權(quán)限運(yùn)行 ldconfig 程序,更新 /etc/ld.so.cache ,a.out運(yùn)行時(shí),就可以找到 libmax.so。
但作為一個(gè)簡單的測試?yán)樱屛覀兏膭?dòng)系統(tǒng)的東西,似乎不太合適。
還有另一種簡單的方法,就是為a.out指定 LD_LIBRARY_PATH。
LD_LIBRARY_PATH=. ./a.out
程序就能正常運(yùn)行了。LD_LIBRARY_PATH=. 是告訴 a.out,先在當(dāng)前路徑尋找鏈接的動(dòng)態(tài)庫。
對于elf格式的可執(zhí)行程序,是由ld-linux.so*來完成的,它先后搜索elf文件的 DT_RPATH 段, 環(huán)境變量 LD_LIBRARY_PATH, /etc/ld.so.cache文件列表, /lib/,/usr/lib目錄, 找到庫文件后將其載入內(nèi)存.
makefile讓工作自動(dòng)化
編寫makefile,內(nèi)容如下:
.PHONY: build test clean build: libmax.so libmax.so: max.o gcc -o $@ -shared $< max.o: max.c gcc -c -fPIC $< test: a.out a.out: test.c libmax.so gcc test.c -L. -lmax LD_LIBRARY_PATH=. ./a.out clean: rm -f *.o *.so a.out
make build就會(huì)生成libmax.so, make test就會(huì)生成a.out并執(zhí)行,make clean會(huì)清理編譯和測試結(jié)果。
到此這篇關(guān)于詳解Linux動(dòng)態(tài)庫生成與使用指南的文章就介紹到這了,更多相關(guān)Linux動(dòng)態(tài)庫生成內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。