1.
靜態庫:
所有編譯器都提供一種機制,將所有相關的目標檔案模組兒打包成乙個單獨的檔案,被稱為靜態庫。它可以用作來聯結器的輸入,當聯結器構造乙個輸入的可執行檔案時,它只拷貝靜態庫裡面被應用程式引用的模組兒。
在unix
系統中,靜態庫以存檔(一組連線起來的可重定位目標檔案的集合,有乙個頭部來描述成員目標檔案的大小和位置)的檔案格式存在於磁碟中。
使用靜態庫的例子:
(1)addvec.c
檔案void addvec(int *x,int *y,int *z,int n)
(2)multvec.c檔案:
void multvec(int *x,int *y,int *z,int n)
(3)用
vector.h
檔案宣告兩個函式的原型:
void addvec(int *x,int *y,int *z,int n);
void multvec(int *x,int *y,int *z,int n);
(4)用
ar工具建立靜態庫
libvector.a:
gcc–c addvec.c multvec.c
arrcs libvector.a addvec.o multvec.o
(5)main.c
檔案:#include
#include"vector.h"
int main()
;inty[2]=;
intz[2];
addvec(x,y,z,2);
printf("z=[%d %d]\n",z[0],z[1]);
return0;
}(6)
編譯執行:
gcc –o2 –c main.c
gcc –static –o p2 main.o ./libvector.a
-static
引數是告訴編譯器驅動程式,聯結器應該構建乙個完全鏈結的可執行目標檔案,它可以載入到儲存器並執行,在載入時無需更進一步的來鏈結。 2
:共享庫:(
動態鏈結由動態聯結器執行
)共享庫也稱為共享目標,在
unix
系統中用
.so字尾表示,微軟中使用共享庫陳偉
dll(動態共享庫);
共享庫的兩種共享方式:(
1)在任何系統中,對於乙個庫只有乙個
.so檔案,所有引用該庫的可執行目標檔案共享這個
.so檔案中的**和資料,而不是像靜態庫一樣將引用的內容拷貝和嵌入到可執行程式中。(
2)在儲存器中,乙個共享庫的
.text
節的乙個副本可以被不同的正在執行的程序共享。
1)在應用程式執行之前,也就是說在應用程式被載入的時候,動態載入器載入和鏈結任意共享庫(
2)應用程式在執行時要求動態載入器載入和鏈結任意共享庫,而無須在編譯時鏈結哪些庫到應用中。(
unix
提供了乙個介面,允許應用程式在執行時載入和鏈結共享庫)
#include
void*dlopen(const char * filename,int flag);
成功返回控制代碼的指標,失敗返回
null.
flag
引數:(1)rtld_now:
告訴聯結器立即解析對外部符號的引用。
(2)rtld_lazy:
高速聯結器推遲符號解析直到執行來自庫中的**。
#include
void*dlsym(void *handle,char *symbol);
成功返回指向符號的指標,出錯為
null
,第一引數是前面已經開啟的共享庫的控制代碼,第二個引數是乙個符號的名字
#include
intdclose(void *handle);
成功返回
0,出錯返回
-1,沒有其他共享庫正在使用這個共享庫,
dlclose
函式就解除安裝該共享庫
#include
constchar *dlerror(void);
對於dlopen,dlsym,dlclose
的呼叫失敗,則返回出錯資訊,成功,則返回
null
例子:(1)
生成共享庫
:gcc –shared –fpic –o libvector.so addvec.cmultvec.c
-fpic
:告訴編譯器生成與位置無關的**。
(2)main1.c
檔案:#include
#include
#include
intx[2]=;
inty[2]=;
intz[2];
intmain()
/*get a pointer to the addvec() function wejust loaded*/
addvec = dlsym(handle,"addvec");
if((error = dlerror()) != null)
/*now we can call addvec() just like anyother function*/
addvec(x,y,z,2);
printf("z = [%d%d]\n",z[0],z[1]);
/*unload the shared library*/
if(dlclose(handle) < 0)
}(3)
執行編譯:
gcc –rdynamic –o2 p3 main1.c –ldl
–rdynamic
引數,告訴編譯器,對於符號解析而言,全域性符號也可用。
注意:如
gcc -0 p2 main1.c./libvector.a
,建立乙個
p2的慕白哦檔案。這個檔案執行時可以和
libvector.a
鏈結。建立可執行檔案時,靜態執行一些鏈結,程式載入時,動態完成鏈結過程。
載入器載入執行
p2時,
p2包含乙個
.interp
節,這個節包含動態聯結器的路徑名。載入器並不是將控制交給應用程式,而是載入和執行動態聯結器。
然後動態聯結器完成重定位任務,再將控股之傳遞給應用程式。
靜態庫與共享庫
編寫使用靜態庫 靜態庫 共享庫 是包含了目標檔案的檔案,這些目標檔案被稱為模板或成員,是可以重用的預編譯 它們以特殊的格式和乙個表或者對映儲存在一起,這個表或者對映將符號名和儲存該符號的成員名字鏈結起來。對映加速了編譯和鏈結過程,靜態庫一般以副檔名.a 代表存檔檔案,archive 命名。為了使用庫...
靜態庫與共享庫
庫library 靜態庫在編譯連線時就把庫里的 提取出來放入可執行檔案中,程式執行時不再依賴庫。動態庫在編譯連線時只記錄了要用的名字在哪個庫的檔案中,執行時才庫檔案中找這個檔案中名字 函式或變數 並且訪問它 1 靜態庫 歸檔 lib a 1 生成庫 gcc c 1.c 2.c 只編譯不連線,產生.o...
靜態庫與共享庫
庫是預先編譯好的方法的結合,是由二進位制可執行 組成,可以被載入記憶體中執行。在linux平台,庫通常放在 lib或者 usr lib中。命名 lib a 檔案格式 由眾多的可執行檔案 o 的打包 整合特點 在鏈結階段,會把整個庫中的 整合到程式中,所以最終編譯的可執行程式的大小比較大,但好處是編譯...