標籤:
參考部落格 http://www.cnblogs.com/feisky/archive/2010/03/09/1681996.html
上述部落格中關於靜態庫與動態庫的講解,很清晰!
庫的定義:
庫從本質上來說是一種可執行代碼的二進位格式,可以被載入記憶體中執行。庫分靜態庫和動態庫兩種。
靜態庫和動態庫的區別
1. 靜態函數庫
這類庫的名字一般是libxxx.a;利用靜態函數庫編譯成的檔案比較大,因為整個 函數庫的所有資料都會被整合進目標代碼中,他的優點就顯而易見了,即編譯後的執行程式不需要外部的函數庫支援,因為所有使用的函數都已經被編譯進去了。當然這也會成為他的缺點,因為如果靜態函數庫改變了,那麼你的程式必須重新編譯。
2. 動態函數庫
這類庫的名字一般是libxxx.so;相對於靜態函數庫,動態函數庫在編譯的時候 並沒有被編譯進目標代碼中,你的程式執行到相關函數時才調用該函數庫裡的相應函數,因此動態函數庫所產生的可執行檔比較小。由於函數庫沒有被整合進你的程式,而是程式運行時動態申請並調用,所以程式的運行環境中必須提供相應的庫。動態函數庫的改變並不影響你的程式,所以動態函數庫的升級比較方便。
linux系統有幾個重要的目錄存放相應的函數庫,如/lib /usr/lib。
樣本:
靜態庫的編譯與使用:
1 //***static_lib1.c*** 2 #include <unistd.h> 3 #include <fcntl.h> 4 #include <stdio.h> 5 6 int printSelf1() 7 { 8 printf("I am static lib 1\n"); 9 return 0;10 }
1 //***static_lib2.c*** 2 #include <unistd.h> 3 #include <fcntl.h> 4 #include <stdio.h> 5 6 int printSelf2() 7 { 8 printf("I am static lib 2\n"); 9 return 0;10 }
1 //***main.c*** 2 #include <unistd.h> 3 #include <fcntl.h> 4 #include <stdio.h> 5 6 int main() 7 { 8 printSelf1(); 9 printSelf2();10 return 0;11 }
#***makefile***main:main.c static_lib gcc main.c -L. -lstatic_lib -o main#***just compile c filestatic_lib1:static_lib1.c gcc -c static_lib1.c#***just compile c filestatic_lib2:static_lib2.c gcc -c static_lib2.c#***create statlic lib***static_lib:static_lib1.o static_lib2.o ar -rsv libstatic_lib.a static_lib1.o static_lib2.o rm -rf static_lib1.o static_lib2.oclean: rm -rf main rm -rf libstatic_lib.a
執行步驟:
[[email protected] static_lib]$ makecc -c -o static_lib1.o static_lib1.ccc -c -o static_lib2.o static_lib2.car -rsv libstatic_lib.a static_lib1.o static_lib2.or - static_lib1.or - static_lib2.orm -rf static_lib1.o static_lib2.ogcc main.c -L. -lstatic_lib -o main[[email protected] static_lib]$ ar -t libstatic_lib.a static_lib1.ostatic_lib2.o[[email protected] static_lib]$ ./main I am static lib 1I am static lib 2
註: ar 命令與靜態庫相關,用於出庫已經查詢庫資訊
動態庫的編譯與使用:
1 //***dynamic.c*** 2 #include <unistd.h> 3 #include <fcntl.h> 4 #include <stdio.h> 5 6 int printSelf() 7 { 8 printf("this is a dynamic lib src\n"); 9 return 0;10 }
1 //***main.c*** 2 #include <unistd.h> 3 #include <fcntl.h> 4 #include <stdio.h> 5 6 int main() 7 { 8 printSelf(); 9 return 0;10 }
#***makefile***main:main.c dynamic_lib gcc main.c -L. -ldynamic_lib -o main #***create dynamic lib libdynamic_lib.sodynamic_lib:dynamic.c gcc -fPIC -shared dynamic.c -o libdynamic_lib.soclean: rm -rf main
編譯成功後執行步驟如下:
[[email protected] dynamic_lib]$ ./main./main: error while loading shared libraries: libdynamic_lib.so: cannot open shared object file: No such file or directory[[email protected] dynamic_lib]$ export LD_LIBRARY_PATH=.[[email protected] dynamic_lib]$ csh[[email protected] dynamic_lib]$ setenv LD_LIBRARY_PATH .[[email protected] dynamic_lib]$ ldd -r mainlinux-gate.so.1 => (0x00b9b000)libdynamic_lib.so => ./libdynamic_lib.so (0x0084a000)libc.so.6 => /lib/libc.so.6 (0x008dd000)/lib/ld-linux.so.2 (0x008bf000)[[email protected] dynamic_lib]$ ./mainthis is a dynamic lib src
註:直接執行會報錯,因為沒有定義LD_LIBRARY_PATH環境變數時,動態庫的尋找路徑只是/usr/lib, /lib; 只有設定了環境變數才可以找到動態庫;
使用ldd -r main 就是檢查庫的依賴關係
其中csh命令是切換使用者的shell為cshell, 使用者登入預設shell為bash,這裡做切換隻是為了示範在csh,bash下分別如何設定環境變數。
對於在代碼中動態調用動態庫的方式這裡就不記錄了,可以參考文章開頭中的部落格,覺得寫得挺好
【Linux 相關】 靜態庫與動態庫的編譯和使用