有空間域名服務(wù)器怎么做網(wǎng)站搜索引擎營(yíng)銷的模式有哪些
目錄
????????1.前言
????????2.靜態(tài)鏈接庫(kù)
????????3.靜態(tài)鏈接庫(kù)生成步驟
????????4.靜態(tài)鏈接庫(kù)的使用
????????5.動(dòng)態(tài)鏈接庫(kù)
????????6.動(dòng)態(tài)鏈接庫(kù)生成步驟
????????7.動(dòng)態(tài)鏈接庫(kù)的使用
????????8.動(dòng)態(tài)鏈接庫(kù)無(wú)法加載
????????9.解決動(dòng)態(tài)鏈接庫(kù)無(wú)法加載問(wèn)題
前言
? ? ? ? 在《MinGW:從入門到鏈接庫(kù)》博客中簡(jiǎn)單介紹了如何編譯動(dòng)態(tài)鏈接庫(kù)和靜態(tài)鏈接庫(kù),本篇博客將詳細(xì)的對(duì)Linux下編譯動(dòng)態(tài)鏈接庫(kù)和靜態(tài)鏈接庫(kù)以及使用進(jìn)行講解,刨析創(chuàng)建庫(kù)文件的時(shí)候Linux做了哪些操作。本篇博客將從靜態(tài)鏈接庫(kù)講起,再到動(dòng)態(tài)鏈接庫(kù)的講解,并配上演示圖片
靜態(tài)鏈接庫(kù)
????????靜態(tài)鏈接庫(kù)是一組編譯后的代碼和資源,它們?cè)诰幾g時(shí)被整合到最終的可執(zhí)行文件中。其靜態(tài)鏈接庫(kù)在不同系統(tǒng)的命名規(guī)則如下:
? ? ? ? 1..Linux下的動(dòng)態(tài)鏈接庫(kù)的命名規(guī)則為lib+文件名+.a,所以Linux中以.a結(jié)尾的文件,一般可以視為靜態(tài)鏈接庫(kù)的文件
示例:libWild.a
? ? ? ? 2.Windows下的動(dòng)態(tài)鏈接庫(kù)的命名規(guī)則為lib+文件名+.lib,所以以.lib結(jié)尾的文件,一般可以視為靜態(tài)鏈接庫(kù)的文件
示例:libWild.lib
????????靜態(tài)鏈接庫(kù)的優(yōu)缺點(diǎn)如下
? ? ? ? ? ? ? ? 優(yōu)點(diǎn):
? ? ? ? ? ? ? ? ? ? ? ? 1.庫(kù)代碼已經(jīng)包含在可執(zhí)行文件中,不需要攜帶額外的庫(kù)文件
? ? ? ? ? ? ? ? ? ? ? ? 2.執(zhí)行速度快,因?yàn)椴僮飨到y(tǒng)不需要在運(yùn)行時(shí)解析外部庫(kù)
????????????????缺點(diǎn):
? ? ? ? ? ? ? ? ? ? ? ? 1.增加了可執(zhí)行文件的大小,因?yàn)槠潇o態(tài)鏈接庫(kù)包含了所有代碼
? ? ? ? ? ? ? ? ? ? ? ? 2.如果庫(kù)更新,需要重新編譯整個(gè)應(yīng)用程序,編譯時(shí)間長(zhǎng)
靜態(tài)鏈接庫(kù)生成步驟
? ? ? ? 在了解了靜態(tài)鏈接庫(kù)的特點(diǎn)以及不同系統(tǒng)下的命名方式后,我們需要著手生成一個(gè)靜態(tài)鏈接庫(kù)文件:
????????1.使用-c命令生成匯編文件
//使用-c命令生成匯編文件
g++ -c -I "頭文件路徑" *.cpp
????????2.使用ar命令打包生成靜態(tài)鏈接庫(kù)
//使用ar命令生成靜態(tài)鏈接庫(kù)
ar rcs 靜態(tài)鏈接庫(kù)名.a 匯編文件.o//ar rcs libfun.a fun.o
//其中r代表替換.o文件,c代表庫(kù)不存在則生成,s代表生成索引文件
? ? ? ? 可參考下圖生成靜態(tài)鏈接庫(kù):
圖1.生成靜態(tài)鏈接庫(kù)
靜態(tài)鏈接庫(kù)的使用
????????當(dāng)使用命令生成一個(gè)可用的靜態(tài)鏈接庫(kù)后,我們需要將其源文件與靜態(tài)鏈接庫(kù)放到同一個(gè)目錄中,然后根據(jù)頭文件編寫代碼, 對(duì)靜態(tài)庫(kù)中的函數(shù)進(jìn)行調(diào)用
? ? ? ? 1.將源文件與靜態(tài)鏈接庫(kù)鏈接產(chǎn)生可執(zhí)行文件???????
//方法1
g++ 源文件.o -o 可執(zhí)行文件名 靜態(tài)鏈接庫(kù)路徑//方法2
g++ 源文件.o -o 可執(zhí)行文件名 -L靜態(tài)鏈接庫(kù)路徑//方法3,其中靜態(tài)鏈接庫(kù)名為除去lib和.a的名稱
//例如libfun.a,其靜態(tài)鏈接庫(kù)名就為fun
g++ 源文件.o -o 可執(zhí)行文件名 -L靜態(tài)鏈接庫(kù)路徑 -l靜態(tài)鏈接庫(kù)名
圖2.多種方法生成靜態(tài)鏈接庫(kù)可執(zhí)行文件
????????PS:如果提示找不到頭文件的定義,需要使用-L和-l命令,其含義如下:
-L: 指定庫(kù)所在的路徑
-l: 指定庫(kù)的名字, 需要去掉前綴lib和后綴.a示例:g++ Code.o -o Code -L ./ -l fun
//其中fun為靜態(tài)鏈接庫(kù)libfun.a
動(dòng)態(tài)鏈接庫(kù)
????????動(dòng)態(tài)鏈接庫(kù)在程序運(yùn)行時(shí)被加載,而不是在編譯時(shí)。它允許多個(gè)程序共享同一份庫(kù)代碼。其命名規(guī)則如下:
? ? ? ? 1..Linux下的動(dòng)態(tài)鏈接庫(kù)的命名規(guī)則為lib+文件名+.so,所以Linux中以.so結(jié)尾的文件,一般可以視為動(dòng)態(tài)鏈接庫(kù)的文件
示例:libWild.so
? ? ? ? 2.Windows下的動(dòng)態(tài)鏈接庫(kù)的命名規(guī)則為lib+文件名+.dll,所以以.dll結(jié)尾的文件,一般可以視為動(dòng)態(tài)鏈接庫(kù)的文件
示例:libWild.dll
? ? ? ? 動(dòng)態(tài)鏈接庫(kù)的優(yōu)缺點(diǎn)如下:
????????????????優(yōu)點(diǎn):
? ? ? ? ? ? ? ? ? ? ? ? 1.減少了內(nèi)存占用,因?yàn)槎鄠€(gè)程序可以共享同一份庫(kù)代碼
? ? ? ? ? ? ? ? ? ? ? ? 2.庫(kù)的更新只需要更新DLL文件本身,不需要重新編譯使用該庫(kù)的應(yīng)用程序
? ? ? ? ? ? ? ? ? ? ? ? 3.可以動(dòng)態(tài)加載和卸載,提供更高的靈活性
????????????????缺點(diǎn):
? ? ? ? ? ? ? ? ? ? ? ? 1.運(yùn)行時(shí)需要加載庫(kù),可能會(huì)稍微增加啟動(dòng)時(shí)間
? ? ? ? ? ? ? ? ? ? ? ? 2.如果庫(kù)文件被其他程序占用或損壞,可能會(huì)導(dǎo)致程序無(wú)法正常運(yùn)行
動(dòng)態(tài)鏈接庫(kù)生成步驟
? ? ? ? 在了解了動(dòng)態(tài)鏈接庫(kù)的特點(diǎn)以及不同系統(tǒng)下的命名方式后,我們需要著手生成一個(gè)動(dòng)態(tài)鏈接庫(kù)文件:
????????1.使用-c命令生成匯編文件
//使用-c命令生成匯編文件
g++ -c -I "頭文件路徑" *.cpp
????????2.使用-shared命令生成動(dòng)態(tài)鏈接庫(kù)
//使用-shared命令生成動(dòng)態(tài)鏈接庫(kù)
g++ -o 動(dòng)態(tài)鏈接庫(kù).dll -I "頭文件路徑" -fPIC -shared *.cpp
圖3.生成動(dòng)態(tài)鏈接庫(kù)
動(dòng)態(tài)鏈接庫(kù)的使用
????????當(dāng)使用命令生成一個(gè)可用的動(dòng)態(tài)鏈接庫(kù)后,我們需要將其源文件與動(dòng)態(tài)鏈接庫(kù)放到同一個(gè)目錄中,然后根據(jù)頭文件編寫代碼, 對(duì)動(dòng)態(tài)庫(kù)中的函數(shù)進(jìn)行調(diào)用
? ? ? ? 1.將源文件與靜態(tài)鏈接庫(kù)鏈接產(chǎn)生可執(zhí)行文件???
//方法1
g++ 源文件.o -o 可執(zhí)行文件名 動(dòng)態(tài)鏈接庫(kù)路徑//方法2
g++ 源文件.o -o 可執(zhí)行文件名 -L動(dòng)態(tài)鏈接庫(kù)路徑//方法3,其中動(dòng)態(tài)鏈接庫(kù)名為除去lib和.dll的名稱
//例如libfun.dll,其靜態(tài)鏈接庫(kù)名就為fun
g++ 源文件.o -o 可執(zhí)行文件名 -L動(dòng)態(tài)鏈接庫(kù)路徑 -l動(dòng)態(tài)鏈接庫(kù)名
圖4.多種方法生成動(dòng)態(tài)鏈接庫(kù)可執(zhí)行文件
????????PS:倘若出現(xiàn)未定義的頭文件等錯(cuò)誤,則可以參考靜態(tài)鏈接庫(kù)生成可執(zhí)行文件的方法,使用-L與-l命令指定庫(kù)地址
動(dòng)態(tài)鏈接庫(kù)無(wú)法加載
? ? ? ? 首先為啥這種無(wú)法加載的問(wèn)題會(huì)出現(xiàn)在動(dòng)態(tài)鏈接庫(kù)?而不是靜態(tài)鏈接庫(kù)。是由于在生成可執(zhí)行文件時(shí),靜態(tài)鏈接庫(kù)會(huì)被打包到可執(zhí)行程序中。當(dāng)程序執(zhí)行時(shí),靜態(tài)鏈接庫(kù)庫(kù)中的代碼也會(huì)加載到系統(tǒng)的內(nèi)存當(dāng)中,因此不會(huì)出現(xiàn)靜態(tài)鏈接庫(kù)找不到無(wú)法被加載的問(wèn)題
? ? ? ? 而動(dòng)態(tài)鏈接庫(kù)在打包時(shí)只是檢測(cè)庫(kù)文件是否存在,存在則打包,不存在則不打包。所以動(dòng)態(tài)鏈接庫(kù)并沒(méi)有被打包到可執(zhí)行文件中,只是在文件中記錄了動(dòng)態(tài)鏈接庫(kù)的名字。所以當(dāng)程序執(zhí)行時(shí),會(huì)存在動(dòng)態(tài)鏈接庫(kù)無(wú)法加載的問(wèn)題
解決動(dòng)態(tài)鏈接庫(kù)無(wú)法加載問(wèn)題
????????在Linux系統(tǒng)中,我們可以使用動(dòng)態(tài)鏈接器來(lái)解決這個(gè)問(wèn)題。動(dòng)態(tài)鏈接器是一個(gè)在程序運(yùn)行時(shí)負(fù)責(zé)鏈接程序與動(dòng)態(tài)鏈接庫(kù)的程序,其尋找鏈接庫(kù)的步驟如下:
? ? ? ? ????????1.編譯時(shí)指定路徑:如果編譯時(shí)通過(guò)特定的編譯器選項(xiàng)(如在Linux中的-Wl,-rpath
)指定了庫(kù)的運(yùn)行時(shí)搜索路徑,動(dòng)態(tài)鏈接器會(huì)首先在這些路徑中搜索庫(kù)
? ? ? ? ????????2.環(huán)境變量:動(dòng)態(tài)鏈接器會(huì)檢查環(huán)境變量來(lái)確定庫(kù)的搜索路徑。例如,在Linux系統(tǒng)中,LD_LIBRARY_PATH
環(huán)境變量可以添加額外的庫(kù)搜索路徑;在Windows系統(tǒng)中,PATH
環(huán)境變量用于搜索.dll
文件
? ? ? ? ????????3.標(biāo)準(zhǔn)庫(kù)目錄:操作系統(tǒng)會(huì)預(yù)定義一些標(biāo)準(zhǔn)目錄來(lái)存放系統(tǒng)級(jí)的庫(kù)。例如,在Linux中,/lib
和/usr/lib
是常見(jiàn)的庫(kù)目錄;在Windows中,系統(tǒng)目錄(如C:\Windows\System32
)是搜索.dll
文件的地方
? ? ? ? ? ? ? ? 4.可執(zhí)行文件所在目錄:動(dòng)態(tài)鏈接器會(huì)搜索可執(zhí)行文件所在的目錄
? ? ? ? 解決方法如下:
????????????????1: 將庫(kù)路徑添加到環(huán)境變量LD_LIBRARY_PATH中:
? ? ? ? ? ? ? ? ? ? ? ? 1.找到相關(guān)的配置文件
~/.bashrc:用戶路徑,只對(duì)當(dāng)前用戶有效
/etc/profile:系統(tǒng)路徑,對(duì)所有用戶有效
? ? ? ? ? ? ? ? ? ? ? ? 2.修改配置文件
#添加動(dòng)態(tài)鏈接庫(kù)路徑
export LD_LIBRARY_PATH =$LD_LIBRARY_PATH :動(dòng)態(tài)鏈接庫(kù)的絕對(duì)路徑
圖5.將庫(kù)路徑添加到環(huán)境變量LD_LIBRARY_PATH
? ? ? ? ? ? ? ? ? ? ? ? 3.執(zhí)行更新命令
source ~/.bashrc //用戶路徑
source /etc/profile //系統(tǒng)路徑//source命令用于執(zhí)行指定文件
? ? ? ? ? ? ? ? 2.更新/etc/ld.so.cache文件:
? ? ? ? ? ? ? ? ? ? ? ? 1.打開(kāi)ld.so.cache文件
sudo vim /etc/ld.so.conf
? ? ? ? ? ? ? ? ? ? ? ? 2.更新 /etc/ld.so.conf中的數(shù)據(jù)到 /etc/ld.so.cache 中
sudo ldconfig
圖6.更新/etc/ld.so.cache文件
? ? ? ? PS:關(guān)于動(dòng)態(tài)鏈接庫(kù)和靜態(tài)鏈接庫(kù)的生成與使用還需要更多的實(shí)踐才能更靈活的運(yùn)用,所以不要停留在紙上談兵的階段,計(jì)算機(jī)專業(yè)并不是什么文科,不需要通篇背誦,多實(shí)操,多練,多發(fā)現(xiàn)問(wèn)題,多解決問(wèn)題