linux 靜態庫動態庫封裝問題

2021-07-11 14:10:11 字數 3271 閱讀 9549

在linux下類庫主要有靜態庫和動態庫兩種庫,首先呢,就說說這兩種庫的差異:

靜態庫:

在程式連線的時候會自動的連線到程式裡,

所以一但編譯完成,靜態庫也就不需要了。靜態庫通常以.a結尾。

例如:libutil.a libuuid.a libz.a等。

動態庫:

在程式編譯時並不會被連線到目標**中,而是在程式執行是才被載入,

因此在程式執行時還需要動態庫存在。通常以.so結尾。如:libz.so。

因此,靜態庫相對於共享庫來說有更高的效率但是也要消耗更多的空間。

值得注意的是,如果既有靜態庫又有動態庫,在編譯時預設的使用動態庫。

在建立自己的靜態庫或者動態庫時候我想,絕大部分人也都會覺得很輕鬆,下面就直接貼步驟

靜態庫:

(1) 編寫庫檔案testlib.c

(2)編寫乙個標頭檔案用於宣告我們使用的函式testlib.h

(3) 編譯testlib.c:    

gcc -c testlib.c

(4) 用ar建立乙個歸檔檔案:    

ar crv libfirst.a testlib.o         生成libfirst.a

(5)在某些系統中還要為靜態庫生成乙個內容表

ranlib libfirst.a

(6)然後就可以使用該靜態庫了

eg:[root@localhost source]# vi zyx.c

[root@localhost source]# gcc -o zyx zyx.c -i./lib -l./lib -lfirst (-static)

[root@localhost source]# ls

hello helloworld.h static.exe zyx

helloworld.cpp lib staticlibtest.c zyx.c

[root@localhost source]# ./zyx

動態庫:

通過乙個例子來介紹如何生成乙個動態庫。這裡有乙個標頭檔案:so_test.h, 三個.c檔案:test_a.c、test_b.c、test_c.c

我們將這幾個檔案編譯成乙個動態庫:libtest.so。

gcc test_a.c test_b.c test_c.c -fpic -shared -o libtest.so

我們已經成功生成了乙個自己的動態鏈結庫libtest.so,

下面我們通過乙個程式來呼叫這個庫里的函式。假設程式的原始檔為:test.c

將test.c與動態庫libtest.so鏈結生成執行檔案test: $ gcc test.c -l. -ltest -o test

測試是否動態連線,如果列出libtest.so,那麼應該是連線正常了

在使用動態庫的時候,還有一點會經常遇到的需要注意:

呼叫動態庫的時候有幾個問題會經常碰到,有時,明明已經將庫的標頭檔案所在目錄 

通過 「-i」 include進來了,庫所在檔案通過 「-l」引數引導,並指定了「-l」

的庫名,但通過ldd命令察看時,就是死活找不到你指定鏈結的so檔案,這時你要作

的就是通過修改ld_library_path或者/etc/ld.so.conf檔案來指定動態庫的目錄。

通常這樣做就可以解決庫無法鏈結的問題了 

1.修改/etc/ld.so.conf,加入自己的動態庫的路徑

然後/sbin/ldconfig 使配製檔案生效

2。直接把自己的動態庫檔案拷貝到 /etc/ld.so.conf中的任意路徑

3.export ld_library_path=/home/kui/:$ld_library_pat(=的前後不能有空格)或者export

$ld_library_path:ld_library_path=/home/kui/

使用echo $ld_library_path可以看到路徑是否設定成功

上面這些都是最基本的,在工作中,這些往往滿足不了我們的需要,比如說,我們生成乙個動態庫,要依賴與多個動態庫或者靜態庫,或者我生成靜態庫的時候要依賴於其它的靜態庫,這個時候怎麼弄?

關於依賴於多個靜態庫或者動態庫生成乙個動態庫的,網上有很多資源,也不多說,直接貼乙個示例:

gcc -gprotocol.c-fpic -sharedlibadd.a libade.a-olibscanapi.so

-i ./ -l ./-lfrt6-i /usr/local/include/libusb-1.0/ -l /usr/local/lib/-lusb-1.0

在這裡面,我生成了乙個 

libscanapi.so

的庫,它依賴於靜態庫 libadd.a libade.a(靜態庫如若是自己編譯的,在編譯時候要加上-fpic -shared),動態庫

libfrt6.so和libusb-1.0.so。其中,-i後面接的是庫標頭檔案路徑, -l後面接的是庫路徑,如果還有更多的靜態庫或者動態庫需要被依賴,則在後面一次新增

關於靜態庫,似乎可用的資料就不是那麼多了

前不久遇到這樣的乙個問題,我依賴於幾個.c檔案和兩個靜態庫的動態庫,需要提供乙個靜態庫版本給客戶,當時感覺很鬱悶,因為兩個靜態庫我都是沒有原始碼的,網上找了許久也沒有找到自己想要的,後來求助一大神,終於完美解決。

我現在找不到那個**了,不過還好儲存的還有截圖,可以參閱一下,同時也建議,如果要經常使用到靜態庫,可以先細讀一下ar的引數。    

其實靜態庫也就相當於乙個壓縮包,裡面存放的是一些.o檔案,把需要的.o放在一起打包,就生成了靜態庫。ar x a.a則正相反,是把生成a.a的.o檔案給解出來,這樣,即便是第三方庫我們也可以獲得其.o。而生成靜態庫的時候正是依賴於.o檔案,所以我們就可以依賴於多個靜態庫生成乙個靜態庫了。

但是有的時候,貌似這樣還會錯誤,比如我上次用的是libusb-1.0.a的靜態庫,在解壓重新打包編譯之後,出現了這樣的問題

從錯誤中,可以很明顯的看到clock和pthread,很明顯,是缺少pthread庫和lrt(實時時鐘)庫的支援,於是在編譯時候在後面加上-lpthread 和-lrt就so easy 解決了

gcc -o tets testscanapi.c -l. -lfp_ara -lpthread -lrt

linux 靜態庫 動態庫

1.概念和區別 靜態庫就是在編譯過程中一些目標檔案的集合。靜態庫在程式鏈結的時候使用,鏈結器會將程式中使用到函式的 從庫檔案中拷貝到應用程式中。一旦鏈結完成,在執行程式的時候就不需要靜態庫了。由於每個使用靜態庫的應用程式都需要拷貝所用函式的 所以靜態鏈結的檔案會比較大。相對於靜態函式庫,動態函式庫在...

linux 靜態庫 動態庫

linux支援兩種庫的型別 靜態庫和動態庫 共享庫 1.linux靜態庫和動態庫的命名規則 靜態函式庫 lib a 動態函式庫 lib so 這些庫檔案都是由 o檔案生成的 動態庫 程式執行過程中進行連線。可執行檔案 庫檔案 靜態庫 編譯時進行連線。庫檔案 的複製貼上過程。程式執行時先檢查依賴的庫檔...

Linux動態庫,靜態庫

1.庫是什麼?庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。就是將源 轉化為二進位制格式的源 相當於進行了加密,別人可以使用庫,但是看不到庫中的內容。2.靜態庫 靜態函式庫時在程式執行之前 編譯 就加入到目標程式中去了 linux中命名系統中靜態庫庫的規則 靜態庫檔名的命名方式是 l...