1. 程式人生 > >C語言中庫文件的加載方式

C語言中庫文件的加載方式

部分函數 HA 靜態 區分 最大 靜態鏈接 open 返回函數 接收


Linux下使用庫有三種方式,靜態鏈接庫,動態鏈接庫和動態加載庫。
-靜態鏈接庫: 在編譯過程中,將所需要的庫文件生成a文件並直接鏈接到最終的可執行文件當中,所以相對來講,靜態方式生成的image大小最大,對外界依賴小。
-動態鏈接庫: 在編譯過程中,不會將庫文件鏈接到最終的可執行文件當中,當程序運行之初會加載所需要的動態庫。知道程序運行結束在卸載,如果運行時無法找到對應的庫文件,運行失敗。
-動態加載庫: 編譯過程跟動態鏈接庫並無區別。在運行方式上,當需要加載庫文件的時候,需要顯式的調用動態庫。程序顯得稍微復雜一點,優點也是明顯的,占用的內存最小。


如何區分三種編譯方法
從Makefile中可以做出簡單的判斷。
gcc test.cpp -L. -ltestlib
gcc會默認加載動態庫,如果沒有動態庫則加載靜態庫,所以可以查看生成的庫的後綴為a還是so。
對於動態加載庫,在編譯過程中,並不需要顯式加載庫文件。與之相對應的,需要在代碼中顯式的加載庫文件,更加靈活。

int (*add) (int a, int b);   //聲明函數指針,用來接收dlsym返回來的函數,就是接收要用到的函數
void *phandle = dlopen("libtest.so", RTLD_LAZY);
add = dlsym(phandle, "add");   //參數add是庫裏定義的add函數,dlsym返回函數地址
printf("%d\n", add(2, 5));

Linux的動態庫中還有另外一個特點,動態庫在加載過程中,會執行_init()函數做初始化,在卸載時默認執行_fini()做些收尾的工作。
即:如果一個可執行文件包含了動態鏈接庫,並且動態鏈接庫設置了_init()函數,就會發現有一部分函數,會在main函數調用之前執行。

C語言中庫文件的加載方式