linux動態庫與靜態庫混合連線

2021-09-06 11:55:51 字數 2774 閱讀 2455

1, 在應用程式需要連線外部庫的情況下,linux預設對庫的連線是使用動態庫,在找不到動態庫的情況下再選擇靜態庫。使用方式為:

gcc test.cpp -l. -ltestlib

如果當前目錄有兩個庫libtestlib.so libtestlib.a 則肯定是連線libtestlib.so。如果要指定為連線靜態庫則使用:

gcc test.cpp-l. -static -ltestlib

使用靜態庫進行連線。

2, 當對動態庫與靜態庫混合連線的時候,使用-static會導致所有的庫都使用靜態連線的方式。這時需要作用-wl的方式:

gcc test.cpp -l.-wl,-bstatic -ltestlib  -wl,-bdynamic -ltestlib 

3, 另外還要注意系統的執行庫使用動態連線的方式,所以當動態庫在靜態庫前面連線時,必須在命令列最後使用動態連線的命令才能正常連線

,如:gcc test.cpp -l. -wl,-bdynamic -ltestlib -wl,-bstatic -ltestlib -wl,-bdynamic 

1、使用gcc建立和使用靜態庫

(1)gcc –o mylib.o –c mylib.c  //生成o檔案

(2)ar -rcs libmylib.a mylib.o   //生成a檔案

-c create的意思

-r replace的意思,表示當插入的模組名已經在庫中存在,則替換同名的模組。

(3)cp libmylib.a /usr/lib/       //拷貝到預設目錄

(4)編寫程式使用庫中的函式,需要包含相關的標頭檔案,即可用下面的方式進行編譯連線。

gcc –o test test.c -l. -lmylib

-l指定靜態函式庫的位置供查詢,注意l後面還有'.',表示靜態函式庫在本目錄下查詢。

-l則指定了靜態函式庫名,由於靜態函式庫的命名方式是lib***.a,其中的lib和.a忽略。

2、使用gcc建立和使用動態庫

(1)gcc –fpic –o mylib.o –c mylib.c

gcc –shared –o libtt.so mylib.o

-fpic 作用於編譯階段,告訴編譯器產生與位置無關**(position-independent code),則產生的**中,沒有絕對位址,全部使用相對位址,故而**可以被載入器載入到記憶體的任意位置,都可以正確的執行。這正是共享庫所要求的,共享庫被載入時,在記憶體的位置不是固定的。

-shared 作用於鏈結階段,實際傳遞給鏈結器ld,讓其新增作為共享庫所需要的額外描述資訊,去除共享庫所不需的資訊。

(2)也可以直接使用下面一條命令:

gcc –fpic –shared –o libtt.so mylib.c

(3)將動態庫拷貝到linux 的標準庫中,usr/local/lib 或者/usr/lib 或者/lib,使用ldconfig命令載入

cp libttt.so /usr/local/lib

(4) 編譯src 程式使用動態庫,隱式呼叫方法: 在編譯呼叫庫函式**時指明動態庫的位置及名字

gcc –o test test.c  ./usr/lib/libttt.so

(5)編譯src程式使用動態庫,顯示呼叫方法

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

#include

int main() 

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

if(pfunc) 

pfunc(); 

else 

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

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

return 0; 

}  gcc –o test test.c -lttt -l

此時會到系統目錄下去搜素libttt.so檔案,具體搜尋方法見下一節。

3、shell 搜尋動態庫路徑位置的兩種方法

(1) 使用命令匯入動態庫的路徑,命令如下:

export ld_library_path=dir (如/usr/local/lib)

(2) 在/etc/ld.so.conf 檔案中更增加一條,修改後用ldconfig 命令載入修改。

4、其他

(1)ldd命令可以檢視乙個可執行程式依賴的共享庫,

# ldd /bin/ln

=> /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2

=> /lib/ld- linux.so.2 (0×40000000)

可以看到ln命令依賴於libc庫和ld-linux庫

(2)看動態庫包含哪些定義用:

nm -d lib*.so

(3)當生成動態庫時,原始檔又引用其他靜態庫,需要一起寫。這時原始檔裡面不用用extern f();,這樣就不能引入靜態庫。需要直接#include 標頭檔案。

比如,gcc -fexceptions -o2 -o hello.node ./build/release/obj.target/hello/hello.o ./libpanda.a /usr/local/lib/libnfc.a  -shared -fpic

參考:

gcc生成靜態庫和動態庫: 

Linux靜態庫與動態庫

靜態庫 a 靜態庫的 在編譯過程中已經被載入可執行程式,因此體積較大。編譯程式時候需要庫作依賴,執行時候不需要。方便,不再需要外部函式庫支援 缺點 1 因為靜態庫被鏈結後直接嵌入可執行程式中,相當於每乙個可執行程式裡都有乙個庫的副本,浪費空間 2 一旦庫中有bug,需要重新編譯。建立步驟 1 編寫函...

linux動態庫與靜態庫

現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的 都從零開始。盡量不重複做別人已經做過的事,站在巨人的肩膀上 做事情。根據鏈結時期的不同,庫又有 靜態庫和共享庫 動態庫 二者的不同點在於 被載入的時刻不同,靜態庫的 在編譯過程中已經被載入可執行程式,因此體積較大。共享庫的 是在可執行程式執行時...

Linux 靜態庫與動態(共享)庫

不論是在linux還是windows下程式設計,我們都會用到庫,有自身帶的標準庫,也有我們自己寫的庫,庫就是預先編譯好的的方法的集合。linux中的庫可以分為兩種,靜態庫和動態庫,動態庫也稱為共享庫。在linux中,庫名稱都以lib開始,靜態庫名為 lib a,動態庫名為 lib so。靜態庫和動態...