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。靜態庫和動態...