擴展:
- 描述:
a. 動態庫也叫共享庫
b. 動態庫把對一些庫函數的鏈接載入推遲到程序運行的時期(runtime)。
c. 可以實現進程之間的資源共享。
d. 將一些程序升級變得簡單。
e. 甚至可以真正做到鏈接載入完全由程序員在程序代碼中控制。
f. 動態鏈接庫的名字形式爲 “libxxx.so” 後綴名爲 “.so”。
g. windows共享庫是以 .dll 爲後綴的文件。 - 特點:
a. 在程序編譯時並不會被鏈接到目標代碼中,而是在程序運行是才被載入,系統會在動態庫環境變量所指定的目錄下去找對應名字的動態庫。
b. 在程序運行時還需要動態庫存在,
c. 代碼體積較小
d. 不同的應用程序如果調用相同的庫,那麼在內存裏只需要有一份該共享庫的實例。
- 創建動態庫(測試例程在結尾):
a. 將庫源文件編譯成.o的目標文件–> gcc -c mylib.c -o mylib.o //-fPIC 創建與地址無關的編譯程序
b. 將.o文件製作成動態庫文件 --> gcc [-shared] -fPIC -o libmylib.so mylib.o //這裏的-shared是默認的,不寫也可以
c. 編譯test.c 同時鏈接製作的動態庫 --> gcc -o test test.c -L. -lmylib // -L庫的路徑 -l庫名 - 使用ldd命令查看可執行程序所依賴的動態庫:
可以看到libmylib.so動態庫沒有找到,需要配置該動態庫的路徑。
- 配置該動態庫路徑位置路徑 :
動態庫默認路徑爲/lib 或者 /usr/lib,有以下方法配置。
a. 方法1:將libmylib.so動態庫放到/lib 或者 /usr/lib目錄下。
b. 方法2:將動態庫所在的路徑加入配置文件: /etc/ld.so.conf 的後面,如下:
打開文件: sudo vim /etc/ld.so.conf
使用pwd命令查看當前libmylib.so動態庫所在的路徑
ld.so.conf文件裏添加libmylib.so動態庫的路徑,如下一行:
/media/sf_VirtualBox_share/庫的製作
運行動態鏈接庫管理命令:sudo ldconfig
c. 方法3:將動態庫所在的路徑臨時加入到環境變量中: LD_LIBRARY_PATH
執行下面的命令:
export LD_LIBRARY_PATH=./
./表示將當前路徑臨時加入到環境變量中,也就是這個路徑–>
/media/sf_VirtualBox_share/庫的製作
注意: 這個方法只對當前使用的shell終端有效。
- 再次使用ldd命令查看可執行文件所依賴的動態庫
可以看到libmylib.so庫找到了。
- 注意:
將程序與動態庫建立關係時,-L參數用於指定動態庫的具體路徑。-L.表示所要鏈接的庫在當前目錄下。而建立鏈接後需要把動態庫放到指定的位置,這樣在可執行程序運行時能正確加載動態庫。 - ldconfig命令 :
ldconfig 命令的用途,主要是在默認搜尋目錄 (/lib和/usr/lib) 以及動態庫配置文件/etc/ld.so.conf內所列的目錄下,搜索出可共享的動態鏈接庫,進而創建出動態裝入程序 (ld.so) 所需的連接和緩存文件.緩存文件默認爲 /etc/ld.so.cache,此文件保存已排好序的動態鏈接庫名字列表。 - 動態庫與靜態庫混合連接
如果只使用–shared(默認選項)會造成所有的庫都使用動態鏈接的方式。這時候需要使用 - Wl,option將option作爲一個選項傳遞給鏈接器,鏈接器就可以讓後面的庫進行不同方式的鏈接。比如 gcc -L. -o test test.c -Wl,-Bstatic -lmystaticlib -Wl,-Bdynamic -lmysharelib。這裏需要保證動態鏈接放在後面,以讓動態庫(如標準庫)能在默認的共享庫路徑去尋找共享庫。也可以寫成 gcc -L. -o test test.c -Wl,-Bdynamic -lmysharelib -Wl,-Bstatic -lmystaticlib -Wl,-Bdynamic。
- 測試例程:
mylib.c 文件
int myplus(int a,int b);
int mysub(int a,int b);
int myplus(int a,int b)
{
return a + b;
}
int mysub(int a,int b)
{
return a - b;
}
test.c 文件
#include <stdio.h>
int myplus(int a,int b);
extern int mysub(int a,int b);
extern int main(void)
{
int a,b;
printf("請輸入a和b:");
scanf("%d%d",&a,&b);
printf("%d + %d = %d\n",a,b,myplus(a,b));
printf("%d - %d = %d\n",a,b,mysub(a,b));
return 0;
}