linux下動態庫檔案的檔名形如lib***.so
,其中so是 shared object 的縮寫,即可以共享的目標檔案。
在鏈結動態庫生成可執行檔案時,並不會把動態庫的**複製到執行檔案中,而是在執行檔案中記錄對動態庫的引用。
程式執行時,再去載入動態庫檔案。如果動態庫已經載入,則不必重複載入,從而能節省記憶體空間。
linux下生成和使用動態庫的步驟如下:
編寫原始檔。
將乙個或幾個原始檔編譯鏈結,生成共享庫。
通過-l-l***
的gcc選項鏈結生成的lib***.so。
把lib***.so放入鏈結庫的標準路徑,或指定ld_library_path
,才能執行鏈結了lib***.so的程式。
下面通過例項詳細講解。
建立乙個原始檔: max.c,**如下:
int max(int n1, int n2, int n3)
編譯生成共享庫:
gcc -fpic -shared -o libmax.so max.c
我們會得到libmax.so。
實際上上述過程分為編譯和鏈結兩步, -fpic是編譯選項,pic是 position independent code 的縮寫,表示要生成位置無關的**,這是動態庫需要的特性; -shared是鏈結選項,告訴gcc生成動態庫而不是可執行檔案。
上述的一行命令等同於:
gcc -c -fpic max.c
gcc -shared -o libmax.so max.o
為了讓使用者知道我們的動態庫中有哪些介面可用,我們需要編寫對應的標頭檔案。
建立 max.h ,輸入以下**:
#ifndef __max_h__
#define __max_h__
intmax
(int n1, int n2, int n3)
;#endif
建立乙個使用max
函式的test.c,**如下:
#include
#include
"max.h"
intmain
(int argc, char *argv)
gcc test.c -l. -lmax
生成a.out,其中-lmax
表示要鏈結libmax.so
。
-l.
表示搜尋要鏈結的庫檔案時包含當前路徑。
注意,如果同一目錄下同時存在同名的動態庫和靜態庫,比如libmax.so
和libmax.a
都在當前路徑下,
則gcc會優先鏈結動態庫。
執行./a.out
會得到以下的錯誤提示。
./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
檔案搜尋要鏈結的動態庫的。
而/etc/ld.so.cache
是 ldconfig 程式讀取/etc/ld.so.conf
檔案生成的。
(注意,/etc/ld.so.conf
中並不必包含/lib
和/usr/lib
,ldconfig
程式會自動搜尋這兩個目錄)
如果我們把libmax.so
所在的路徑新增到/etc/ld.so.conf
中,再以root許可權執行ldconfig
程式,更新/etc/ld.so.cache
,a.out
執行時,就可以找到libmax.so
。
但作為乙個簡單的測試例子,讓我們改動系統的東西,似乎不太合適。
還有另一種簡單的方法,就是為a.out
指定ld_library_path
。
ld_library_path=. ./a.out
程式就能正常執行了。ld_library_path=.
是告訴a.out
,先在當前路徑尋找鏈結的動態庫。
對於elf格式的可執行程式,是由ld-linux.so*來完成的,它先後搜尋elf檔案的編寫makefile,內容如下:dt_rpath
段, 環境變數ld_library_path
, /etc/ld.so.cache檔案列表, /lib/,/usr/lib目錄, 找到庫檔案後將其載入記憶體. (
.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
就會生成libmax.so
,make test
就會生成a.out
並執行,make clean
會清理編譯和測試結果。 linux 動態庫的生成與使用
linux 圖2.靜態鏈結與動態鏈結return a b 編譯動態庫 gcc shared o libadd.so add.c 生成 libadd.so 動態鏈結方法 在編譯程式時,指定要鏈結的庫檔案即可,此時呼叫共享庫只需要其標頭檔案即可。示例 test.c include include int...
Linux下動態庫 靜態庫的生成與使用
動態庫和靜態庫的介紹 一般情況下,在專案裡會把功能相似的 封裝成庫,方便使用和管理,同時增加了 的內聚性。庫分為兩種,一種為靜態庫,檔名以.a結尾,另一種是動態庫,檔名以.so結尾。靜態庫和動態庫的使用各有利弊。使用靜態庫的好處就是簡單,因為在鏈結的時候直接把靜態庫中的內容鏈結到可執行檔案中,鏈結完...
Linux動態庫生成與使用指南
linux下動態庫檔案的檔名形如lib so,其中so是 shared object 的縮寫,即可以共享的目標檔案。在鏈結動態庫生成可執行檔案時,並不會把動態庫的 複製到執行檔案中,而是在執行檔案中記錄對動態庫的引用。程式執行時,再去載入動態庫檔案。如果動態庫已經載入,則不必重複載入,從而能節省記憶...