Linux 靜態庫與動態庫的生成及呼叫

2021-08-26 19:00:18 字數 4380 閱讀 4436

一,庫:一種可執行**的二進位制形式,可以被載入記憶體執行。其中庫分為靜態庫、動態庫

二,靜態庫和動態庫的區別

1)linux 下靜態庫:名字一般為 lib***.a利用靜態函式庫編譯成的檔案比較大,因為整個 函式庫的所有資料都會被整合進目標**中,他的優點就顯而易見了,即編譯後的執行程式不需要外部的函式庫支援,因為所有使用的函式都已經被編譯進去了。當然這也會成為他的缺點,因為如果靜態函式庫改變了,那麼你的程式必須重新編譯。

2)linux 下動態庫:這類庫的名字一般是lib***.so;相對於靜態函式庫,動態函式庫在編譯的時候 並沒有被編譯進目標**中,你的程式執行到相關函式時才呼叫該函式庫裡的相應函式,因此動態函式庫所產生的可執行檔案比較小。由於函式庫沒有被整合進你的程式,而是程式執行時動態的申請並呼叫,所以程式的執行環境中必須提供相應的庫。動態函式庫的改變並不影響你的程式,所以動態函式庫的公升級比較方便。

linux系統有幾個重要的目錄存放相應的函式庫,如/lib /usr/lib。

三,靜態庫的使用

操作工具:gcc 和 ar 命令

1)設計庫的源**

part1.c:

void print1()

part2.c

void print2()

2)編譯.c檔案:

gcc -o -c part1.c part2.c

生成part1.o 和 part2.o檔案

3)鏈結靜態庫

ar -rsv libpart.a part1.o part2.o

-r replace existing or insert new file(s) into the archive

-s replace existing or insert new file(s) into the archive

-v replace existing or insert new file(s) into the archive

4)呼叫庫的源**

main.c

int main()

5)編譯庫並鏈結庫

gcc -o main main.c -l ./ -lpart //一定不要忘記了 -lpart

解釋: -l 後面跟庫的路徑 -l*** 是靜態庫 lib***.a 中去掉lib 和.a 名字後的

./main //執行

輸出:

this is the first lib src!

this is the second src lib!

四,動態庫的使用1)設計庫** part.c

#include //這個需要加上

int p=8;

void print1()

2)生成動態庫

gcc -o -fpic -shared -o dl.so pr1.c

-fpic :-f後面跟一些編譯選項,pic是其中一種,表示生成位置無關**(position independent code)

3)呼叫函式的寫法

int main()

4)呼叫編譯

gcc -o main ./dl.so

執行: ./main

輸出:

this is the first so src
六,動態庫的顯式呼叫

顯式呼叫動態庫需要四個函式的支援, 函式 dlopen 開啟動態庫, 函式 dlsym 獲取動態庫中物件基址, 函式 dlerror 獲取顯式動態庫操作中的錯誤資訊, 函式 doclose 關閉動態庫.

呼叫**:main.c

#include #include int main() 

pfunc = (void (*)())dlsym(phandle, "print1"); // 獲取庫函式 print 的位址

if(pfunc)

pfunc();

else

printf("can't find function print\n");

p = (int *)dlsym(phandle, "p"); // 獲取庫變數 p 的位址

if(p)

printf("p = %d\n", *p);

else

printf("can't find int p\n");

dlclose(phandle); // 關閉動態庫

return 0;

}

編譯呼叫:gcc -o main main.c -l ./ -ldl

前提:此時還不能立即./main,因為在動態函式庫使用時,會查詢/usr/lib、/lib目錄下的動態函式庫,而此時我們生成的庫不在裡邊。 這個時候有好幾種方法可以讓他成功執行: 最直接最簡單的方法就是把dl.so拉到/usr/lib或/lib中去。 還有一種方法 export ld_library_path=$(pwd) 另外還可以在/etc/ld.so.conf檔案裡加入我們生成的庫的目錄,然後/sbin/ldconfig。 /etc/ld.so.conf是非常重要的乙個目錄,裡面存放的是鏈結器和載入器搜尋共享庫時要檢查的目錄,預設是從/usr/lib /lib中讀取的,所以想要順利執行,我們也可以把我們庫的目錄加入到這個檔案中並執行/sbin/ldconfig 。另外還有個檔案需要了解/etc/ld.so.cache,裡面儲存了常用的動態函式庫,且會先把他們載入到記憶體中,因為記憶體的訪問速度遠遠大於硬碟的訪問速度,這樣可以提高軟體載入動態函式庫的速度了。

我們採用:export ld_library_path=$(pwd) 可以echo $ld_library_path 檢視一下

執行: ./main

輸出:this is the first so src

p = 8

七,庫依賴的檢視

使用ldd命令來檢視執行檔案依賴於哪些庫。

該命令用於判斷某個可執行的 binary 檔案含有什麼動態函式庫。

[root@test root]# ldd [-vdr] [filename]

引數說明:

--version  列印ldd的版本號

-v --verbose  列印所有資訊,例如包括符號的版本資訊

-d --data-relocs  執行符號重部署,並報告缺少的目標物件(只對elf格式適用)

-r --function-relocs  對目標物件和函式執行重新部署,並報告缺少的目標物件和函式(只對elf格式適用)

如果命令列中給定的庫名字包含'/',這個程式的libc5版本將使用它作為庫名字;否則它將在標準位置搜尋庫。執行乙個當前目錄下的共享庫,加字首"./"。

Linux生成動態庫 so與生成靜態庫 a

動態庫共享庫 第一步 通過gcc fpic c 編譯生成.o檔案 gcc fpic c a.c 編譯生成.o檔案 fpic與位置無關 gcc fpic c b.c 生成a.o,b.o編譯檔案。第二步 通過上面已經生成的a.o,b.o檔案生成.so檔案 方法1 gcc shared wl o liba...

Linux動態庫靜態庫的生成

函式庫 1 便於移植,方便使用 2 保密,保護智財權 靜態庫 編譯生成靜態庫 編譯生成靜態庫 1 把.c檔案編譯生成.o檔案 gcc c add.c 或gcc add.c c o add.c 2 把.o檔案編譯生成.a靜態庫 ar rc libadd.a add.o 3 靜態庫的使用 gcc mai...

靜態庫與動態庫的生成

一.靜態庫 靜態庫 a 程式在編譯鏈結時候把庫的 鏈結到可執行 中,程式執行時將不再需要靜態庫。測試程式 add.h ifndef add h define add h int add int x,int y endif add.c include add.h int add int x,int y...