三、linux庫的概念
這裡寫目錄標題
1、概念
一個“程式函式庫”簡單的說就是一個檔案包含了一些編譯好的程式碼和資料,這些編譯好的程式碼和資料可以在事後供其他的程式使用。程式函式庫可以使整個程式更加模組化,更容易重新編譯,而且更方便升級。
(加密)而且在實際程式設計中,有時並不希望使用者看到函式原始碼,就要打包函式庫,讓使用者看不到原始碼。
程式函式庫可分為3種類型:靜態函式庫(static libraries)、共享函式庫(shared libraries)、動態載入函式庫(dynamically loaded libraries):
優點:1、靜態庫被打包到應用程式中,載入速度快
2、釋出程式無需提供靜態庫,因為已經在app中,移植方便
缺點:1、連結時完成地拷貝到可執行檔案中,被多次使用就有多份冗餘拷貝,導致資料量大,耗記憶體;
2、更新部署麻煩,釋出麻煩
2、動態函式庫:同共享函式庫是一個東西(在linux上叫共享物件庫, 檔案字尾是.so ,windows上叫動態載入函式庫, 檔案字尾是.dll)
優點:1、連結時不復制,程式執行時動態載入到記憶體,供程式呼叫,系統只加載一次,多個程式共用,可以節省記憶體;
2、程序升級簡單,因為APP中無庫原始碼,升級後只要庫的名字不變,函式名和引數不變,只是做了優化就拿載入成功。升級優化方便
缺點:1、載入速度比靜態庫慢。
2、釋出程式需要提供依賴的動態庫。
2、庫的製作及使用
準備工作:
1、先在主程式裡包含自己編寫的cal.h
include"cal.h"
補充:include<>與include" "的區別 1
cal.h的內容為:(函式的宣告)
int add(int a,int b);
int minus(int a, int b);
要製作成庫的cal1.C 檔案
int add(int a,int b){
return a+b;
}
int minus(int a, int b){
return a-b;
}
靜態庫的製作
檔名的命名方式是“libxxx.a”,庫名前加”lib”,字尾用”.a”,“xxx”為靜態庫名。
靜態庫:格式xxxx.a
1. gcc cal1.c -c 生成xxx.o檔案
生成了cal1.o檔案
[email protected]:~/test $ gcc cal1.c -c
[email protected]:~/test $ ls
a.out cal1.c cal1.o cal.c cal.h libcal.c
2. xxx.o檔案生成xxx.a靜態庫檔案:ar rcs libcal.a cal1.o 2
生成libcal.a檔案
[email protected]:~/test $ ar rcs libcal.a cal1.o
[email protected]:~/test $ ls
a.out cal1.c cal1.o cal.c cal.h libcal.a libcal.c libcalcufunc.a
靜態庫的使用
指令:
[email protected]:~/test $ gcc cal1.c -lcal1 -L ./ -o mainProStatic
[email protected]:~/test $ ./mainProStatic
請輸入第一個數
1
請輸入第二個數
2
加法:3
減法:-1
cal1.c:含有main函式的“主程式”C檔案
-lcal1: -l是指定要用的庫,cal1為靜態庫名(砍頭去尾);
-L:告訴gcc編譯器從-L制定的路徑去找靜態庫。預設是從/usr/lib /usr/local/lib去找
./:為當前路徑
動態庫
命名規則
格式:libxxx.so
動態庫的製作:
動態庫的建立可以一部到位的把功能 .c 檔案編譯成 .so 檔案,使用下面指令:
生成libcalc.so檔案
gcc -shared -fpic cal1.c -o libcalc.so
-shared:指定生成動態庫
-fpic標準 :fPIC 選項作用於編譯階段,在生成目標檔案時就得使用該選項,以生成位置無關的程式碼。
編譯:
發現會有報錯
報錯原因:那是因為Linux系統在找動態庫的時候,會在 /usr/lib/ 目錄下找檔案;從而找不到libcalc.so這個檔案。
由於靜態庫的檔案是事先編譯好的加進去的所以不需要配置環境變數。而動態庫是程式執行時動態載入的,所以需要尋找。
[email protected]:~/test $ gcc cal.c -lcalc -L ./ -o dynamic
[email protected]:~/test $ ./dynamic
./dynamic: error while loading shared libraries: libcalc.so: cannot open shared object file: No such file or directory
面對這種情況需要
通過環境變數LD_LIBRARY_PATH指定動態庫搜尋路徑。
export LD_LIBRARY_PATH="/home/pi/test"
但是這種方法只能用於這一個視窗,其他視窗就不行了。所以我們可以編寫一個shell指令碼來執行。
指令碼內容
export LD_LIBRARY_PATH="/home/pi/test"
./dynamic
//"dy.sh" [New] 2L, 49C written
建立完成後使用下面的命令給.sh檔案加可執行的許可權然後./dy.sh就可行執行了。
chmod +x dy.sh
一、引用的標頭檔案bai不同
#include < >:引用的是編譯bai器的類庫路徑裡du面的標頭檔案。
#include " ":引用的是你程式目錄dao的相對路徑中的標頭檔案。
二、用法不同
#include < >:用來包含標準標頭檔案(例如stdio.h或stdlib.h).
#include " " :用來包含非標準標頭檔案。
三、呼叫檔案的順序不同
#include < > :編譯程式會先到標準函式庫中呼叫檔案。
#include " " :編譯程式會先從當前目錄中呼叫檔案。
四、預處理程式的指示不同
#include < >:指示預處理程式到預定義的預設路徑下尋找檔案。
#include " " : 指示預處理程式先到當前目錄下尋找檔案,再到預定義的預設路徑下尋找檔案。 ↩︎ar命令:可以用來建立、修改庫,也可以從庫中提出單個模組
引數r:在庫中插入模組(替換)。當插入的模組名已經在庫中存在,則替換同名的模組。如果若干模組中有一個模組在庫中不存在,ar顯示一個錯誤訊息,並不替換其他同名模組。預設的情況下,新的成員增加在庫的結尾處,可以使用其他任選項來改變增加的位置。
引數c:建立一個庫。不管庫是否存在,都將建立。
引數s:建立目標檔案索引,這在建立較大的庫時能加快時間。 ↩︎