建設(shè)一個網(wǎng)站用什么搭建北京搜索排名優(yōu)化
一、靜態(tài)庫(格式:libxxx.a)
1. 原理
- 在運行之前就已經(jīng)把函數(shù)的實現(xiàn)代碼拷進 main.c 文件里了,因此靜態(tài)庫的權(quán)限是沒有可執(zhí)行權(quán)限的,因為根本不會執(zhí)行到靜態(tài)庫里的內(nèi)容。
- 靜態(tài)庫的創(chuàng)建原理本質(zhì)上就是把所有的函數(shù)源文件編譯成 *.o 文件后,再把所有的 *.o 文件合成一個庫,而這個庫就是靜態(tài)庫。
2. 創(chuàng)建
在 makefile 中可這樣創(chuàng)建:
lib=libmylib.a$(lib):add.oar -rc $@ $^
add.o:add.cgcc -c $^.PHONY:clean
clean:rm -rf *.o *.a a.out mylib.PHONY:output
output:mkdir -p mylib/includemkdir -p mylib/libsmv *.h mylib/includemv *.a mylib/libs
3. 使用
a. 頭文件 & 庫的區(qū)別
- 頭文件是以 .h 結(jié)尾的文件
- 庫是以 .a 結(jié)尾的文件
b. 命令(gcc -I -L l...)
// 假如要對 /lib/libmylib.a 進行靜態(tài)連接
gcc -I <頭文件的路徑> -L <靜態(tài)庫的路徑> -lmylib
補充:因為 libmylib 只有靜態(tài)庫的版本,因此 gcc 編譯時只能編成靜態(tài)庫。換句話說,如果同時有 libmylib.a 和 libmylib.so 兩個版本的庫,gcc 編譯時會選擇?libmylib.so ,編成動態(tài)庫。
二、動態(tài)庫(共享庫)(格式:libxxx.so)
1. 原理
在程序運行時會把代碼(函數(shù)的實現(xiàn))加載進內(nèi)存中,然后再調(diào)整頁表的映射關(guān)系,使其虛擬地址在進程地址空間的共享區(qū)中。然后調(diào)用函數(shù)時程序會直接跳轉(zhuǎn)到共享區(qū)執(zhí)行函數(shù)。
2. 創(chuàng)建
在 makefile 中可這樣創(chuàng)建:
lib=libmylib.so$(lib):add.ogcc -shared -o $@ $^
add.o:add.cgcc -fPIC -c $^.PHONY:clean
clean:rm -rf *.o *.so a.out mylib.PHONY:output
output:mkdir -p mylib/includemkdir -p mylib/libsmv *.h mylib/includemv *.so mylib/libs
3. 使用
// 假如要對 /lib/libmylib.so 進行靜態(tài)連接
gcc -I <頭文件的路徑> -L <動態(tài)庫的路徑> -lmylib
4. 優(yōu)勢
因為動態(tài)鏈接的庫可以實現(xiàn)多進程共享,因此可以減少內(nèi)存的使用。
5. 動態(tài)庫如何從磁盤加載到內(nèi)存?
(1)動態(tài)庫如何載入內(nèi)存?
當程序運行到需要調(diào)用動態(tài)庫的代碼時,如果動態(tài)庫此時并沒有載入內(nèi)存,那么操作系統(tǒng)就會把動態(tài)庫載入內(nèi)存;然后修改頁表的映射關(guān)系;而對于進程地址空間,動態(tài)庫的代碼也會載入進程地址空間的共享區(qū);然后進程就可以訪問動態(tài)庫的代碼啦~
如果動態(tài)庫已經(jīng)在內(nèi)存里了,那就直接向當前進程的頁表添加映射關(guān)系;然后動態(tài)庫的代碼載入該進程的共享區(qū);然后進程就可以訪問動態(tài)庫的代碼啦~
(2)進程如何訪問動態(tài)庫的代碼?(通過相對地址)
由于共享區(qū)可能有多個動態(tài)庫,因此動態(tài)庫的起始地址是不確定的,因此如果一個動態(tài)庫的代碼載入共享區(qū),那么這些代碼一定不會用絕對地址來編址。取而代之的是,動態(tài)庫的代碼會采用相對地址編址,然后再加上載入共享區(qū)后獲得的絕對起始地址(設(shè)起始地址的值為 start),那么進程可以通過 start + 相對地址 的方式訪問該動態(tài)庫的代碼。
6. 解決動態(tài)庫加載問題
- 把庫放到程序搜索庫的默認文件里,如 /lib64
- 把庫與程序搜索庫的默認文件建立軟連接,如 mylib -> /lib64
- 把自己的庫路徑添加到環(huán)境變量 LD_LIBRARY_PATH 中
- 在 /etc/ld.so.conf.d 中建立自己的配置文件,然后重新 ldconfig 即可(永久有效)