linux下的動態鏈接庫和靜態鏈接庫到底是個什么鬼?(一)靜態鏈接庫的編譯與使用


    知識不等於技術,這句話真的是越工作的時間長越深有體會,學習到的知識只有不斷的實踐,才成真正在自已的心里扎下根,成為自身的一部分,所以無論如何,我希望我的博客可以一直寫下去,慢慢的沉淀,終會有回報,無聊的時候想想,的確,寫代碼也是一種自娛自樂!

    前幾天在做項目時出了一個問題,大體就是:makefile里在編譯可執行文件testappd的時候在有用-l去引用一個libtest.so,能編譯通過,但是在加載運行的時候系統提示找不到這個lib而導致進程啟動失敗。后來知道在產品版本編譯打包的時候這個lib並未被打包進去,這個問題后來解決了。但是出於好奇,我想搞清楚動態庫和靜態庫的概念,以及之前做過另一個項目時以dlopen方式去引用動態庫和makefile 去引用動態庫這幾種方式的不同。查找了網上的一些資料,看明白了,還需手動驗證一下才放心。

    首先說說靜態鏈接庫,說實話,有時候真心感覺計算機這些相關的各種高大上的詞匯都是紙老虎,看上去高深的不行,其實當你捅開那層紙,就那么回事兒。

     所謂靜態鏈接庫,說白了就是在你把寫好的代碼編譯的時候,就把你引用的庫一起給編進去了,從此后你編出來的執行程序跟外面都不再有任何關系,即使這個庫更新了,你也搭不上邊兒,其次,如果系統中許多類似的程序都需要用到這個庫,那么各自在編譯的時候都需要把這個庫給編進去,浪費存儲空間(加載到內存里應該也是浪費內存空間的)。linux系統中靜態庫的名字一般叫

xxx.a, 所以如果你看到一個以 .a結束的文件那么它多半就是一個靜態鏈接庫文件。

    廢話少說,我們直接上干貨,看看靜態庫是如何被編譯出來以及如何被使用的

    首先我們寫了一個sum.c,如下,很簡單,里面只有一個Sum函數,把兩個數相加的和返回

1 int Sum(int Number1, int Number2)
2 {
3     return Number1 + Number2;
4 }

當然還要寫一個聲明它的sum.h

int Sum(int Number1, int Number2);

最后來一個調用這個sum函數的主函數, 打印返回的結果

 1 #include<stdio.h>
 2 #include<sum.h>
 3 
 4 void main()
 5 {
 6     int Num1 = 1;
 7     int Num2 = 2;
 8     int iRet = 0;
 9 
10     iRet = Sum(Num1, Num2);
11     printf("Num1 + Num2 = %d.", iRet);
12     return;
13 }

接下來我們編譯靜態庫,我的筆記本是mac os環境,打開終端后用vim寫代碼, gcc等相關工具直接就能用,版本沒注意,反正能用就行

 1 192:zch kane$ ls
 2 main.c    sum.c    sum.h
 3 192:zch kane$ gcc -c sum.c
 4 192:zch kane$ ls
 5 main.c    sum.c    sum.h    sum.o
 6 192:zch kane$ 
 7 192:zch kane$ 
 8 192:zch kane$ ar cr libsum.a sum.o
 9 192:zch kane$ ls
10 libsum.a    main.c        sum.c        sum.h        sum.o
11 192:zch kane$ 

如上,我們用ar這個工具來編譯靜態庫,cr標志告訴ar將object文件封裝

然后我們編譯主程序並運行:

192:zch kane$ gcc -o sumappd main.c -L . -lsum
192:zch kane$ ls
libsum.a    main.o        sum.h        sumappd
main.c        sum.c        sum.o
192:zch kane$ ./sumappd 
Num1 + Num2 = 3

“-L .”指明了當前lib所在的路徑是在本目錄,-l表示鏈接libsum.a這個lib庫,很好理解。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM