- 連接器的主要做用是把各個模塊之間互相引用的部分處理好,使得各個模塊之間可以正確的銜接。
- 由連接器在連接時將庫的內容直接加入到可執行文件中
- 編譯靜態庫源碼: gcc-c lib.c -o lib.o
- 生成靜態庫文件: ar -q lib.a lib.o
- 使用靜態庫編譯: gcc main.c lib.a -o main.out
test.c
#include <stdio.h> extern char* name(); extern int add(int a, int b); int main() { printf("Name" %s\n", name()); printf("Result: %d\n", add(2, 3)); return 0; }
slib.c
char* name() { return "Static Lib"; } int add(int a, int b) { return a + b; }
輸出: Name Static Lib Result: 5 gcc -c slib.c -o slib.o ar -q slib.a -o slib.o gcc test.c slib.a -o test.out
- 可執行程序在運行時才動態加載庫進行連接
- 庫的內容不會進入可執行程序當中
stubx : 告訴編譯器動態庫中可以使用的內容編程
- 編譯動態庫源碼: gcc -shared dlib.c -o dlib.so
- 使用動態庫編譯: gcc main.c -ldl -o main.out
關鍵系統調用函數
- dlopen: 打開動態庫文件
- dlsym: 查找動態庫中的函數並返回調用地址
- dlclose: 關閉動態庫文件
test.c
#include <stdio.h> #include <dlfcn.h> extern char* name(); extern int add(int a, int b); int main() { void* pdlib = dlopen("./dlib.so", RTLD_LAZY); char* (*pname)(); int (*padd)(int, int); if( pdlib != NULL ) { pname = dlsym(pdlib, "name"); padd = dlsym(pdlib, "add"); if( (pname != NULL) && (padd != NULL) ) { printf("Name %s\n", pname()); printf("Result: %d\n", padd(2, 3)); } dlclose(pdlib); } else { printf("Cannot open lib ... \n"); } return 0; }
dlib.c
char* name() { return "Static Lib"; } int add(int a, int b) { return a + b; }
輸出: Name Static Lib Result: 5 gcc -shared dlib.c -o dlib.so gcc test.c -ldl -o test.out
- 連接是指將目標文件最終連接爲可執行文件
根據連接方式的不一樣,連接過程能夠分爲:spa
- 靜態連接: 將目標文件直接連接進入可執行程序
- 動態連接: 在程序啓動後才動態加載運行
以上內容參考狄泰軟件學院系列課程,請你們保護原創!code