【转】Linux 静态库与共享库的使用
原文網(wǎng)址:http://blog.csdn.net/heyabo/article/details/11688517
申明: 正如題如示,本篇講的是Linux下是靜態(tài)庫與共享庫,而Window下的動態(tài)鏈接庫詳細(xì)情況可見這篇文章:windows動態(tài)鏈接庫 DLL 淺析。雖然原理,思想差不多,但是細(xì)節(jié)卻各有不同。
?
一、靜態(tài)庫
?
? 1、概念:靜態(tài)庫指將所有相關(guān)的目標(biāo)文件打包成為一個(gè)單獨(dú)的文件-即靜態(tài)庫文件,以.a結(jié)尾。靜態(tài)庫可作為鏈接器的輸入,鏈接器會將程序中使用的到函數(shù)的代碼從庫文件中拷貝到應(yīng)用程序中。一旦鏈接完成,在執(zhí)行程序的時(shí)候就不需要靜態(tài)庫了。 注1:由于每個(gè)使用靜態(tài)庫的應(yīng)用程序都需要拷貝所用函數(shù)的代碼,所以靜態(tài)鏈接的文件會比較大。 注2:在Unix系統(tǒng)中,靜態(tài)庫以一種稱為存檔(archive)的特殊文件格式存放在磁盤中。存檔文件是一組連接起來的可重定位目標(biāo)文件的集合,有一個(gè)頭部用來描述每個(gè)成員目標(biāo)文件的大小和位置(存檔文件名由后綴.a標(biāo)識)。 2、創(chuàng)建與應(yīng)用 假設(shè)我們想在一個(gè)叫做libvector.a的靜態(tài)庫中提供以下向量函數(shù): [cpp]?view plaincopyprint?[cpp]?view plaincopyprint?
使用AR工具創(chuàng)建靜態(tài)庫文件: 為了使用這個(gè)庫,編寫一個(gè)應(yīng)用(其調(diào)用addvec庫中的函數(shù)): [cpp]?view plaincopyprint?
編譯-鏈接-運(yùn)行程序: 注1:-static 參數(shù)告訴編譯器驅(qū)動程序,鏈接器應(yīng)該構(gòu)建一個(gè)完全的可執(zhí)行目標(biāo)文件,它可以加載到存儲器并運(yùn)行,在加載時(shí)無需進(jìn)一步的鏈接 -即一次性靜態(tài)鏈接完畢,不允許存在動態(tài)鏈接。 注2:當(dāng)鏈接器運(yùn)行時(shí),它判定addvec.o定義的addvec符號是被main2.o引用的,所以它拷貝addvec.o到可執(zhí)行文件。因?yàn)槌绦蛑袥]有引用任何由multvec.o定義的符號,所以鏈接器就不會拷貝這個(gè)模塊到可執(zhí)行文件。同時(shí),鏈接器還會拷貝libc.a中的pirintf.o模塊,以及許多C運(yùn)行時(shí)系統(tǒng)中的其他模塊。鏈接器完整的行為可如下圖所示: 二、共享庫 1、概念:共享庫是一個(gè)目標(biāo)模塊(以.so后綴表示),在運(yùn)行時(shí),可以加載到任意的存儲器地址,并和一個(gè)在存儲器中的程序鏈接起來,這個(gè)過程稱為動態(tài)鏈接,是由一個(gè)叫做動態(tài)鏈接器的程序來執(zhí)行的。 2、分類:根據(jù)加載和鏈接共享庫的時(shí)機(jī)又可分為:A)應(yīng)用程序自身加載時(shí)動態(tài)鏈接和加載共享庫;B)應(yīng)用程序運(yùn)行過程中動態(tài)鏈接和加載共享庫兩種情況。 2-A:應(yīng)用程序自身加載時(shí)動態(tài)鏈接和加載共享庫 2-A.1 基本思路是:當(dāng)創(chuàng)建可執(zhí)行文件時(shí),靜態(tài)執(zhí)行一些鏈接(共享庫的重定位和符號表信息,而非代碼和數(shù)據(jù)),然后在應(yīng)用程序加載時(shí),動態(tài)完成鏈接過程。 2-A.2 創(chuàng)建與應(yīng)用 創(chuàng)建類似于靜態(tài)庫的創(chuàng)建,假設(shè)我們現(xiàn)在想在一個(gè)叫做libvector.so的共享庫庫中提供以下addvec和multvec函數(shù): 下面使用-shared選項(xiàng)來指示鏈接器創(chuàng)建一個(gè)共享的目標(biāo)文件(即共享庫),鏈接并運(yùn)行程序: ? 注1:-fPIC選項(xiàng)指示編譯器生成與位置無關(guān)的代碼 其動態(tài)鏈接過程可如下圖所示: 注2:在可執(zhí)行文件p2中沒有拷貝任何libvector.so真正的代碼和數(shù)據(jù)節(jié),而是由鏈接器拷貝了一些重定位和符號表信息,它們使得運(yùn)行時(shí)動態(tài)鏈接器可以解析libvector.so中代碼和數(shù)據(jù)的引用,重定位完成鏈接任務(wù)。其中需要重定位的有:
- 1)重定位libc.so的文本和數(shù)據(jù)到某個(gè)存儲器段;
- 2)重定位libvector.so的文本和數(shù)據(jù)到另一個(gè)存儲器段;
- 3)重定位p2中所有對libc.so和libvector.so定義的符號的引用。
?
例子:
?
[cpp]?view plaincopyprint?
運(yùn)行結(jié)果:-ldl參數(shù):表示生成的對象模塊需要用到共享庫
?
?
Referebces:
?
1.《深入理解計(jì)算機(jī)系統(tǒng)》第7章:鏈接 P448-P479
2.?靜態(tài)庫、共享庫、動態(tài)庫的創(chuàng)建和使用 :http://bbs.chinaunix.net/thread-2037617-1-1.html
3.?Linux 動態(tài)庫剖析:http://www.ibm.com/developerworks/cn/linux/l-dynamic-libraries/
4.?dlopen:?http://baike.baidu.com/link?url=VswI42A-IxFuF5SelbJxDREXuY0BvYWHEdcCYozSNH93ark0nTMi4YdhHrvt-bIo2_F-swU2onuYMNwXeUGVMq
總結(jié)
以上是生活随笔為你收集整理的【转】Linux 静态库与共享库的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Web前端 性能优化
- 下一篇: Linux学习资料-万用字符与特殊符号