c语言仿ce内存搜索工 源代码_C语言函数库:动态库和静态库优缺点比较
函數的重要性
我們在編寫一個C語言程序的時候,經常會遇到好多重復或常用的部分,如果每次都重新編寫固然是可以的,不過那樣會大大降低工作效率,并且影響代碼的可讀性,更不利于后期的代碼維護。我們可以把他們制作成相應的功能函數,使用時直接調用就會很方便,還可以進行后期的功能升級。
例如我要在一段代碼中多次交換兩個變量的值,我可以在代碼中多次寫入:
i=x;
x=y;
y=i;
不過這樣未免有點麻煩我們可以編寫一個change_two_int()函數進行簡化。
定義如下函數:
void change_two_int( int *a,int *b ){int c;c=*a;a=b;*b=c;}
這樣每次要進行交換時只需調用change_two_int(&x , &y);?即可,是否方便了許多?
那么,我們要討論的和這些有什么關系呢?庫通俗的說就是把這些常用函數的目標文件打包在一起,提供相應函數的接口,便于程序員使用。庫是別人寫好的現有的,成熟的,可以復用的代碼,我們只需要知道其接口如何定義,便可以自如使用。
共享庫=靜態庫
現實中每個程序都要依賴很多基礎的底層庫,不可能每個人的代碼都從零開始,因此庫的存在意義非同尋常。比如我們常使用的printf函數,就是C標準庫提供的函數。我們在使用時只需要包含相應的頭文件就可以使用(非靜態編譯還要有相應的庫文件)。而不用關心printf函數具體是如何實現的,這樣就大大提高了程序員編寫代碼的效率。
從使用方法上分庫大體上可以分為兩類:靜態庫和共享庫。
在windows中靜態庫是以.lib為后綴的文件,共享庫是以.dll為后綴的文件。在linux中靜態庫是以.a為后綴的文件,共享庫是以.so為后綴的文件。
以linux下的靜態庫和動態庫為例我們研究一下,首先我們看一下他們的生成方式。
?靜態庫
首先將源文件編譯成目標文件:gcc –c a.c b.c
生成靜態庫:ar –rc libstatic.a a.o b.o
?共享庫
同靜態庫一樣編譯成目標文件:gcc –c a.c b.c
生成共享庫:gcc –fPIC –shared –o libshared.so a.o b.o
由此可見靜態庫和動態庫都是對目標文件的處理,也可以說庫文件已經是機器碼文件了,靜態庫和共享庫的加載過程有很大的區別。
靜態庫的鏈接方法:
gcc –o staticcode –L. –lstatic main.c –static(默認庫在當前文件夾)
共享庫的鏈接方法:
gcc –o sharedcode -L. –lshared main.c(默認庫在當前文件夾)
靜態庫
當程序與靜態庫連接時,庫中目標文件所含的所有將被程序使用的函數的機器碼被copy到最終的可執行文件中。這就會導致最終生成的可執行代碼量相對變多,相當于編譯器將代碼補充完整了,優點是這樣運行起來相對就快些。
不過會有個缺點:占用磁盤和內存空間。靜態庫會被添加到和它連接的每個程序中,而且這些程序運行時,都會被加載到內存中。無形中又多消耗了更多的內存空間。
動態庫
與共享庫連接的可執行文件只包含它需要的函數的引用表,而不是所有的函數代碼,只有在程序執行時, 那些需要的函數代碼才被拷貝到內存中。
優點:這樣就使可執行文件比較小,節省磁盤空間,更進一步,操作系統使用虛擬內存,使得一份共享庫駐留在內存中被多個程序使用,也同時節約了內存。
缺點:不過由于運行時要去鏈接庫會花費一定的時間,執行速度相對會慢一些,總的來說靜態庫是犧牲了空間效率,換取了時間效率,共享庫是犧牲了時間效率換取了空間效率,沒有好與壞的區別,只看具體需要了。
另外,一個程序編好后,有時需要做一些修改和優化,如果我們要修改的剛好是庫函數的話,在接口不變的前提下,使用共享庫的程序只需要將共享庫重新編譯就可以了,而使用靜態庫的程序則需要將靜態庫重新編譯好后,將程序再重新編譯一遍。這也是使用過程當中的差別,以現在的項目舉例,在遠程更新的時候,如果只是*.so動態庫封裝內容變化了,那么只需要更新*.so即可。
總結
?靜態庫和動態庫在兩種系統下存在形式
Windows下:
.dll動態庫
.lib靜態庫
庫即為源代碼的二進制文件
Linux下:
.so動態庫
.a靜態庫
?靜態庫和動態庫的優缺點
靜態庫在程序編譯時會被連接到目標代碼中,程序運行時將不再需要該靜態庫。
動態庫在程序編譯時并不會被連接到目標代碼中,而是在程序運行時才被載入,因此在程序運行時還需要動態庫存在。
(1)庫文件是如何產生的在linux下?
靜態庫的后綴是.a,它的產生分兩步:
由源文件編譯生成一堆.o,每個.o里都包含這個編譯單元的符號表。
ar命令將很多.o轉換成.a,成文靜態庫。
動態庫的后綴是.so,它由gcc加特定參數編譯產生。
例如:
gcc?fPIC?c?.cgcc?fPIC?c?.c gcc -shared -Wl,-soname, libfoo.so.1 -olibfoo.so.1.0 *.
(2)庫文件是如何命名的,有沒有什么規范?
在linux下,庫文件一般放在/usr/lib和/lib下:
靜態庫的名字一般為libxxxx.a,其中xxxx是該lib的名稱。
動態庫的名字一般為libxxxx.so.major.minor,xxxx是該lib的名稱,major是主版本號, minor是副版本號。
(3)如何知道一個可執行程序依賴哪些庫?
ldd命令可以查看一個可執行程序依賴的共享庫。
例如 #ldd /bin/lnlibc.so.6,可以看到ln命令依賴于libc庫和ld-linux庫:
=> /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2
=> /lib/ld- linux.so.2 (0×40000000)
(4)可執行程序在執行的時候,如何定位共享庫文件?
當系統加載可執行代碼時候,能夠知道其所依賴的庫的名字,但是還需要知道絕對路徑。此時就需要系統動態載入器(dynamiclinker/loader)。
總結
以上是生活随笔為你收集整理的c语言仿ce内存搜索工 源代码_C语言函数库:动态库和静态库优缺点比较的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos8更换yum源_基于yum进
- 下一篇: 疲劳驾驶数据集_人工检查,11 个类、9