title: 動態庫和靜態庫
date: 2019-06-16 17:38:12
tags:
- Linux
categories:
- Linux
動態鏈接庫、靜態鏈接庫。
庫的命名規則
Linux 下,以 lib 開頭,.a
結尾是靜態庫,.so
結尾是動態庫。
Windows 下,以 lib 開頭,.lib
是靜態庫,.dll
是動態庫。
靜態庫
Windows 下 的後綴是 .lib,Linux 下的後綴是 .a。
把一些 .o 文件打包到一起生成了一種特殊的二進制程序,自身不能直接執行,但是可以和其他的 .c/.cpp 文件一起編譯生成一個新的可執行程序,這個新的可執行程序就可以單獨發佈出去了。
**應用場景:**發佈小型程序的時候,就可以使用靜態庫的方式編譯生成一個單獨的可執行程序,並且不依賴其他的庫,發佈比較方便。
栗子 mymath.a
// add.h
#pragma once
int add(int a, int b);
// add.c
#include "add.h"
int add(int a, int b) {
return a + b;
}
// sub.h
#pragma once
int sub(int, int);
// sub.c
#include "sub.h"
int sub(int a, int b) {
return a - b;
}
// main.c
#include <stdio.h>
#include "sub.h"
#include "add.h"
int main(void) {
int a = 10, b = 10;
printf("add(20, 10) = %d\n", add(a, b));
printf("sub(20, 10) = %d\n", sub(a, b));
return 0;
}
[外鏈圖片轉存失敗(img-AZo3bAaB-1563257997059)(https://i.loli.net/2019/06/16/5d06115c7d6a781665.png)]
生成靜態庫
ar -rc libmymath.a add.o sub.o
ar 是 GNU 歸檔工具;rc 表示(replace and create)
查看靜態庫中的目錄列表
ar -tv libmymath.a
t 列出靜態庫中的文件;v 詳細信息(verbose)。
編譯
gcc main.c -L. -lmymath
-L 指定庫路徑,在當前目錄下;-l 指定庫名。
動態庫
把一些 .c/.cpp 文件編譯成了一種特殊的二進制程序,自身不能直接執行,但是可以被其他可執行程序調用。在可執行文件開始運行以前,外部函數的機器碼由操作系統從磁盤上的該動態庫中複製到內存中,這個過程稱爲動態鏈接(dynamic linking)。
動態庫可以在多個程序間共享,所以動態鏈接使得可執行文件更小,節省了磁盤空間。操作系統採用虛擬內存機制允許物理內存中的一份動態庫被要用到該庫的所有進程共用,節省了內存和磁盤空間。
**應用場景:**客戶端更新時不必要更新整個程序,而是隻更新其中的一部分模塊。其中的模塊就是以動態鏈接庫的方式組織的。
栗子 mymath.so
生成動態庫
gcc -fPIC -c sub.c add.c
-fPIC 產生位置無關碼(position independent code)
gcc -shared -o libmymath.so *.o
-shared 表示生成共享庫格式
使用動態庫
gcc main.c -L. -lmymath
-L 指定路徑;-l 指定動態庫名稱。
查看某個程序的動態庫依賴
-
Linux 下
ldd exeFileName
[外鏈圖片轉存失敗(img-5bxU35KB-1563257997060)(https://i.loli.net/2019/06/16/5d0618971448496206.png)]
-
Mac 下
otool -L execFileName
運行動態庫
有的時候可能找不到庫,就需要配置下了。
-
拷貝.so文件到系統共享庫路徑下,一般指
/usr/lib
-
更改 LIBRARY_PATH 環境變量
export LD_LIBRARY_PATH=.
-
ldconfig 配置
/etc/ld.so.conf.d/
,ldconfig更新
庫的搜索路徑
- 從左到右搜索 -L 指定的目錄。
- 由環境變量指定的目錄(LIBRARY_PATH,設定這個環境變量來提醒系統去哪些目錄找動態庫)
- 由系統指定的目錄(
/usr/lib /usr/local/lib
)