歡迎您光臨本站 註冊首頁

Unix動態庫和靜態庫比較

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

靜態庫和動態庫的區別

文件預覽

文件目錄樹如下,如你所見,非常簡單.

1. libtest/ 2. |-- lt.c 3. |-- lt.h 4. `-- test.c #lt.c 1. 4. 5. #include 6. 7. void myprint(void) 8. { 9. printf("Linux library test!n"); 10. } # lt.h 1. 4. 5. void myprint(void); #test.c 1. 4. 5. #include "lt.h" 6. 7. int main(void) 8. { 9. myprint(); 10. return 0; 11. }

先看靜態庫

首先做成靜態庫 liblt.a .

1. $ gcc -o lt.o -c lt.c 2. $ ar cqs liblt.a lt.o再者,鏈接,1. $ gcc test.o liblt.a -o test這個時候再來看他的引用庫情況.

1. $ ldd test 2. linux-gate.so.1 => (0xffffe000) 3. libc.so.6 => /lib/libc.so.6 (0xb7e29000) 4. /lib/ld-linux.so.2 (0xb7f6e000)

動態庫

做成動態庫 liblt.so .

1. $ gcc -o lt.o -c lt.c 2. $ gcc -shared -Wall -fPIC -o liblt.so lt.o -shared 該選項指定生成動態連接庫(讓連接器生成T類型的導出符號表,有時候也生成弱連接W類型的導出符號),不用該標誌外部程序無法連接.相當於一個可執行文件-fPIC:表示編譯為位置獨立的代碼,不用此選項的話編譯后的代碼是位置相關的動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的.

-L.:表示要連接的庫在當前目錄中-ltest:編譯器查找動態連接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.so來確定庫的名稱LD_LIBRARY_PATH:這個環境變數指示動態連接器可以裝載動態庫的路徑.

鏈接方法I,拷貝到系統庫里再鏈接,讓gcc自己查找1. $ sudo cp liblt.so /usr/lib 2. $ gcc -o test test.o -llt這裡我們可以看到了 -llt 選項,-l[lib_name] 指定庫名,他會主動搜索lib[lib_name].so.這個搜索的路徑可以通過 gcc --print-search-dirs來查找.

鏈接方法II,手動指定庫路徑1. $ cc -o test test.o -llt -B /path/to/lib這裡的-B 選項就添加 /path/to/lib 到gcc搜索的路徑之中.這樣鏈接沒有問題但是方法II中手動鏈接好的程序在執行時候仍舊需要指定庫路徑(鏈接和執行是分開的).需要添加系

統變數LD_LIBRARY_PATH :

1. $ export LD_LIBRARY_PATH=/path/to/lib

這個時候再來檢測一下test程序的庫鏈接狀況(方法I情況)

1. $ ldd test 2. linux-gate.so.1 => (0xffffe000) 3. liblt.so => /usr/lib/liblt.so (0xb7f58000) 4. libc.so.6 => /lib/libc.so.6 (0xb7e28000) 5. /lib/ld-linux.so.2 (0xb7f6f000)恩,是不是比靜態鏈接的程序多了一個 liblt.so ?恩,這就是靜態與動態的最大區別,靜態情況下,他把庫直接載入到程序里,而在動態鏈接的時候,他只是保留介面,將動態庫與程序代碼獨立.這樣就可以提高代碼的可復用度,和降低程序的耦合度.

另外,運行時,要保證主程序能找到動態庫,動態庫一般發布到系統目錄中,要麼就在跟主程序相對很固定的路徑里,這樣不管主程序在本機何時何地跑,都能找得到動態庫.而靜態庫只作用於鏈接時,運行主程序時,靜態庫文件沒存在意義了.

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/iejwduan/archive/2009/03/26/4027808.aspx


[火星人 ] Unix動態庫和靜態庫比較已經有564次圍觀

http://coctec.com/docs/linux/show-post-52471.html