一、頭文件和庫文件
頭文件提供聲明,庫文件提供定義/實現。
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
執行此命令后也可以生成可執行程序