撰寫 C 語言時,除了必須用的 header file 之外,另外一個重要角色,就是 library 了! 而 library 又分為兩種:
- static library (副檔名為 .a)
- shared library (副檔名為 .so.N)
Static Library
所謂的 static library,其實沒很特別,只是一堆 object file 的集合而已,以下介紹 static library 的用法。
假設有兩個 function 分別位於不同的 file 中:
另外設計一支程式,使用到上面所定義的 function:// ==================== fred.c ====================
#include <stdio.h>
void fred(int arg) {
printf("fred: we passed %d\n", arg);
} //end fred
// ==================== bill.c ====================
#include <stdio.h>
void bill(char *arg) {
printf("bill: we passed %s\n", arg);
} //end bill
接著是編譯的方式,有幾種方式可以進行編譯:// ==================== program.c ====================
#include <stdlib.h>
#include "lib.h"
int main(void) {
bill("Hello World!");
exit(0);
} //end main
# (1) 直接將主程式與 function file 一同編譯其中第三種是比較標準的作法,不過其實 gcc 的功能很強,所以在編譯的時候可以省略一些指令卻可以達到相同效果。
shell> gcc -o program program.c bill.c
# (1) 將定義兩個 function 的檔案編譯成 object file
# (2) 將主程式與 object file 一同進行編譯
shell> gcc -c fred.c bill.c ; gcc -o program program.c bill.o
# (1) 將定義兩個 function 的檔案編譯成 object file
# (2) 產生 static library (archive)
# (3) 將主程式與 static library 一同進行編譯
shell> gcc -c fred.c bill.c ; ar -crv libfoo.a fred.o bill.o ; gcc -o program program.c libfoo.a
# (1) 將定義兩個 function 的檔案編譯成 object file
# (2) 產生 static library (archive)
# (3) 將主程式與 static library 一同進行編譯(-L 指定 library directory、-l 指令所要用的 library name)
shell> gcc -c fred.c bill.c ; ar -crv libfoo.a fred.o bill.o ; gcc -o program program.c -L. -lfoo
Shared Library
談到 shared library 之前,必須先說明 static library 的缺點,就是當很多程式都使用相同的 static library 時,會在 memory 中產生多份相同的 copy,無形之中造成記憶體很多浪費,因此才會有 shared library 的出現。
shared library 存放的位置跟 static library 大致上是相同的,不過副檔名為 .so.N (N 為重新修改的次數)。
使用 shared library,即時同時被多個程式所使用,系統也只要在 memory 中存有一份資料即可,比起 static library 是節省記憶體許多。
而其運作的方式,在一開始時,shared library 是不會被載入 memory 中,而是當主程式執行時(此時主程式被載入 memory 中),將主程式所使參照使用到的 share library 在執行期間載入 memory 中執行。
接著,用來處理主程式與 shared library 參照工作的程式,稱為 ld.so(或是 ld-linux.so.N),而相關設定檔位於 /etc/ld.so.conf 中,若是設定有任何改變,則需要執行 ldconfig 指令重建參照的工作。
最後,若要查詢一個程式執行時所需求的 shared library,可使用以下指令:
shell> ldd program
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e89000) # 需求 libc.so 這個 shared library
/lib/ld-linux.so.2 (0xb7fdf000)
書本的code: http://media.wiley.com/product_ancillary/28/04701476/DOWNLOAD_COMBINED/780470147627_download.zip
回覆刪除