靜態、共用和動態庫

來源:互聯網
上載者:User
C語言中有一些函數不需要進行編譯,有一些函數也可以在多個檔案中使用。一般來說,這些函數都會執行一些標準任務,如資料庫輸入/輸出操作或螢幕控制等。可以事先對這些函數進行編譯,然後將它們放置在一些特殊的目標代碼檔案中,這些目標代碼檔案就稱為庫。庫檔案中的函數可以通過串連程式與應用程式進行串連。這樣就不必在每次開發程式時都對這些通用的函數進行編譯了。

  不同類型的應用程式將會使用不同的函數庫。例如:libdbm庫中組包含了對資料庫檔案進行訪問的dbm函數,需要對資料庫進行操作的程式就會與該庫進行串連。數學應用程式將使用數學庫libm,X-Windows應用程式將使用Xlib庫,libX11。另外,所有的程式都將使用標準的C函數庫。libc,該庫中包含了諸好記憶體管理或輸入輸出操作的基本函數,這些庫都存放在/usr/lib這些系統公用的目錄中,系統中的任何使用者都可以利用這些庫。當然使用者也可以建立自己專用的庫函數,供自己或其它指定的人員使用。

  庫可以有三種使用的形式:靜態、共用和動態。靜態庫的代碼在編譯時間就已串連到開發人員開發的應用程式中,而共用庫只是在程式開始運行時才載入,在編譯時間,只是簡單地指定需要使用的庫函數。動態庫則是共用庫的另一種變化形式。動態庫也是在程式運行時載入,但與共用庫不同的是,使用的庫函數不是在程式運行開始,而是在程式中的語句需要使用該函數時才載入。動態庫可以在程式運行期間釋放動態庫所佔用的記憶體,騰出空間供其它程式使用。由於共用庫和動態庫並沒有在程式中包括庫函數的內容,只是包含了對庫函數的引用,因此代碼的規模比較小。

  已經開發的大多數庫都採取共用庫的方式。ELF格式的可執行檔使得共用庫能夠比較容易地實現,當然使用舊的a.out模式也可以實現庫的共用。Linux系統中目前可執行檔的標準格式為ELF格式。

  GNU庫的使用必須遵守Library GNU Public License(LGPL許可協議)。該協議與GNU許可協議略有不同,開發人員可以免費使用GNU庫進行軟體開發,但必須保證向使用者提供所用的庫函數的原始碼。

  系統中可用的庫都存放在/usr/lib和/lib目錄中。庫檔案名稱由首碼lib和庫名以及尾碼組成。根據庫的類型不同,尾碼名也不一樣。共用庫的尾碼名由.so和版本號碼組成,靜態庫的尾碼名為.a。採用舊的a.out格式的共用庫的尾碼名為.sa。

  libname.so.major.minor
  libname.a

  這裡的name可以是任何字串,用來唯一標識某個庫。該字串可以是一個單字、幾個字元、甚至一個字母。數學共用庫的庫名為libm.so.5,這裡的標識字元為m,版本號碼為5。libm.a則是靜態數學庫。X-Windows庫名為libX11.so.6,這裡使用X11作為庫的標識,版本號碼為6。

  使用gcc編譯器就可以將庫與自己開發的程式串連起來,例如:libc.so.5中包含了標準的輸入輸出函數,當串連程式進行目標代碼串連時會自動搜尋該程式並將其串連到產生的可執行檔中。標準的輸入輸出庫中包含了許多基本的輸入輸出函數,如printf函數等。也可以串連其它的一些系統函數庫,如數學庫等,但與libc.so.5不同,大部分其它的系統庫需要在命令列中顯式指定所用的庫名。

  在/usr /lib和/lib目錄中可以找到絕大多數的共用庫。串連時將首先搜尋這兩個目錄。有一些庫也可能存放在特定的目錄中,在/etc/ld.conf設定檔中給出了這些目錄的列表。串連程式也會對列出的這些目錄進行搜尋。在預設情況下,Linux將首先搜尋指定庫的共用版本,如果找不到,才會去搜尋靜態版本。在對共用庫進行更新或安裝新庫後,必須運行ldconfig命令更新/etc/ld.conf檔案中相應的項(如果使用RPM進行安裝,一般會自動進行更新,不過也不能保證這一點)。

  在gcc編譯器中引用可搜尋到的目錄中的庫檔案時,需要使用-l選項和庫名。在gcc命令列上輸入-lm可以在程式中串連標準算術庫,-l將首先使用libname.so進行搜尋,這裡是libm.so。下面的例子將使用算術庫建立bookrecs 程式,請注意這裡的-lm選項。

  $ gcc main.c io.c -o bookrecs -lm

  系統中還有一些其它可用的庫,常用的是libncurses.a庫,包含了一些簡單的滑鼠移動常式。在命令列中使用-lncurses選項引用libncurses.so庫。下面的例子同時調用了數學和游標庫。

  $ gcc mian.c io.c -o bookrecs -lm -lncurses

  在引用其它目錄中的庫時,需要使用-ldir選項指定該目錄。該選項指定了搜尋庫函數時其它路徑。在下面的例子中,使用者在串連時使用了mydir目錄中的myio.so庫檔案。

  $ gcc main.c -o bookrecs -lmydir -lmyio

  .a的是為了支援較老的a.out格式的可執行檔的
  .so的是支援elf格式的可執行檔的庫。

  靜態庫是指編譯串連時,把庫檔案的代碼全部加入到可執行檔中,所以產生的檔案較大, 但運行時,就不再需要庫檔案了。動態庫正好相反,在編譯串連時,沒有把庫檔案的代碼加入到可執行檔中,所以產生的檔案較小,但運行時,仍需要載入庫檔案

  .a是靜態庫檔案,可以用ar 命令產生。
  .so是動態庫檔案,編譯時間加上指定的選項即可產生,具體選項看相應的系統文檔了。。。。

  IBM AIX下如下:
  $(CC) $(SHOPT) $(SHLIBS) a.o b.o -o lib$@$(DBBUILDTAIL)

  假設你有test1.c test2.c test3.c , 編寫成動態連結程式庫
  1. 先編譯成test1.o test2.o test3.o
  2. gcc -shared -W1, -soname,libvTest.so.1 -o libvTest.so.1.0 *.o

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.