1. 程式人生 > >Linux--標頭檔案和庫檔案(靜態庫和動態庫)

Linux--標頭檔案和庫檔案(靜態庫和動態庫)

一、標頭檔案和庫檔案

標頭檔案提供宣告,庫檔案提供定義/實現。
C程式碼的編譯過程:預處理(需要標頭檔案) -> 編譯 -> 彙編 -> 連結(需要庫檔案); 執行時可能還有動態連結過程。
編譯的時候,只要有標頭檔案中的宣告就足夠了。在連結的時候,把已經編譯好的.obj和現有的.lib檔案進行連結,這時就可以最終生成可執行檔案了。其實標頭檔案與其實現檔案或相應lib檔案都沒有直接的聯絡。標頭檔案是告訴編譯器函式是如何去呼叫如何返回的,所有實現都是分別編譯,最後在連結階段鏈在一起。

標頭檔案包含宣告,庫檔案包含實現或者與DLL庫的連線。

所以,如果在程式碼裡要用到這些函式那麼就要包含標頭檔案,編譯的時候才能知道這些函式的原形 ;

在進行程式碼連線的時候就需要庫檔案了,這時聯結器就把函式的實現程式碼(靜態庫)連線到你的程式或者將你的函式呼叫連線到相應的DLL的對應函式(動態庫) 。

lib是靜態庫,編譯的時候程式碼直接插入到你的程式 ,DLL是動態庫,編譯的時候,只是產生一些呼叫DLL內程式碼的匯入表,真正執行的時候是呼叫的DLL內的程式碼。

總結起來就是,庫檔案通過標頭檔案向外匯出介面。使用者通過標頭檔案找到庫檔案中函式實現的程式碼從而把這段程式碼連結到使用者程式中去。

.a代表傳統的靜態函式庫(也稱作歸檔檔案:archive)

.so代表共享函式庫

二、建立靜態庫檔案

1.建立原始檔willku1.c和willku2.c

2.編譯原始檔生成.o檔案(將要包含在庫檔案中的目標檔案)

gcc -c willku1.c willku2.c =>willku1.o willku2.o

3.建立標頭檔案ishead.h

內容:void willku1(char *);
           void willku2(int);

4.建立應用程式app.c(將呼叫willku2.c檔案)

#include “ishead.h”

5.編譯、測試應用程式app.c

gcc -c app.c

gcc -o app app.o willku2.o

./app

6.建立並使用庫檔案(.a),使用ar建立歸檔檔案並將目標檔案加進去。

ar歸檔檔案:將若干單獨檔案歸併到一個大檔案中,以建立歸檔檔案或集合。

ar crv libwill.a willku1.o willku2.o

(ranlib libwill.a)

7.app.c使用函式庫libwill.a

gcc -o app app.o libwill.a #gcc -o app app.o -L. -lwill

./app

三、動態庫的生成及使用

靜態庫有很多缺點,所以有必要使用動態庫。

  1. 動態連結庫是程式執行時載入的庫,當動態連結庫正確安裝後,所有的程式都可以使用動態庫來執行程式。動態連結庫是目標檔案的集合,目標檔案在動態連結庫中的組織方式是按照特殊方式形成的。庫中函式和變數的地址是相對地址,不是絕對地址,其真實地址在呼叫動態庫的程式載入時形成。

  2. 動態連結庫的名稱有別名(soname),真名(realname)和連結名(linker name)。別名由一個字首lib,然後是庫的名字,再加上一個字尾“.so”構成。真名是動態連結庫真實名稱,一般總是在別名的基礎加上一個小版本號,釋出版本等構成。除此之外,還有一個連結名,即程式連結時使用的庫的名字。

  3. 在動態連結庫安裝的時候,總是複製檔案到某個目錄下,然後用一個軟連線生成別名,在庫檔案進行更新的時候,僅僅更新軟連結即可。

生成和使用動態庫

1.看一個例項來了解如何自己生成靜態庫和使用靜態庫

建立程式檔案

1>在test資料夾下有三個檔案: main.c ,add.c,sub.c,tiger.h

2> main.c檔案中的內容:

3>.tiger.h檔案中的內容:

4>.add.c檔案中的內容

5>.sub.c檔案中的內容

動態庫的生成

1>首先生成目標檔案,但是此時要加編譯器選項-fpic和連結器選項-shared,

gcc -fpic -c add.c

gcc -fpic -c sub.c

生成中間檔案add.o和sub.o

2>其次生成動態庫

gcc -shared –o libtiger.so add.o sub.o

生成動態庫 libtiger.so,libtiger.so就是我們生成的目標動態庫。我們以後使用動態庫和main.c程式生成可執行程式

以上兩部也可以合成一步搞定:

gcc -fpic -shared add.c sub.c -o libtiger.so

2.使用動態連結庫

在編譯程式時,使用動態連結庫和靜態庫是一致的,使用”-l庫名”的方式,在生成可執行檔案的時候會連結庫檔案。

1>使用命令:

gcc -o main main.c -L ./ -ltiger

2>-L指定動態連結庫的路勁,-ldtiger連結庫函式tiger。-ltiger是動態庫的呼叫規則。Linux系統下的動態庫命名方式是lib*.so,而在連結時表示位-l*,*是自己命名的庫名。

3>但是程式會提示如下錯誤

error while loading shared libraries: libtiger.so: cannot open shared object file: No such file or direct

這是因為程式執行時沒有找到動態連結庫造成的。程式編譯時連結動態庫和執行時使用動態連結庫的概念是不同的,在執行時,程式連結的動態連結庫需要在系統目錄下才行。

4>使用以下方法可以解決此問題

a. 在linux下最方便的解決方案是拷貝libtiger.so到絕對目錄 /lib 下(但是,要是超級使用者才可以,因此要使用sudo哦,親)。就可以生成可執行程式了

b.第二種方法是:將動態連結庫的目錄放到程式搜尋路徑中,可以將庫的路徑加到環境變數LD_LIBRARY_PATH中實現:

export LD_LIBRARY_PATH=‘pwd’:$LD_LIBRARY_PATH

執行此命令後也可以生成可執行程式。