首先說明一下頭文件、庫文件、庫函數這三個概念的區別。頭文件:即後綴爲.h的文件,在其中對變量和函數原型進行了聲明。庫文件:提供有庫函數的文件。一種是靜態連接的後綴爲.a的文件,在程序編譯時連接;一種是共享庫,文件後綴爲.so,在程序運行的時候才進行連接。庫函數:在庫文件裏提供的函數。
下面,我們用一個實例介紹一下怎麼樣創建庫文件以及怎麼樣應用庫文件。
#ifndef MYMATH_H
#define MYMATH_H
int xiangjia(int a,int b);
int xiangjia(int a,int b);
int xiangjia(int a,int b)
int xiangjian(int a,int b)
文件4:main.c
#include "mymath.h"
#include “stdio.h”
int main()
{
printf(“%d”,xiangjia(65,45));
printf(“%d”,xiangjian(65,45));
無論動態庫還是靜態庫都需要用到.o文件來生成,先編譯生成.o文件。
# gcc -c xiangjia.c xiangjia.c main.c
靜態庫文件名的命名規範是以lib爲前綴,緊接着跟靜態庫名,擴展名爲.a。例如:我們將創建的靜態庫名爲math56,則靜態庫文件名就是libmath56.a。
# ar cr libmath56.a xiangjia.o xiangjian.o
#gcc –o math main.o libmath56.a
或者 # gcc –o math main.c –L. –lmath56
執行:
動態庫文件擴展名爲.so,使用下面的命令可以生成l ibmath56.so文件。
# gcc -shared -fPCI -o libmath56.so xiangjia.o xiangjia.o
# gcc –o math2 main.c -L. –lmath56
./math: error while loading shared libraries: libmath56.so: cannot open shared object file: No such file or directory
嘔哦,出錯了!快看看錯誤提示,原來是找不到共享庫文件libmath56.so。程序在運行時,會在/usr/lib和/lib等目錄中查找需要的動態庫文件。若找到,則載入動態庫,否則將提示類似上述錯誤而終止程序運行。
(2)在LD_LIBRARY_PATH環境變量中加上庫所在路徑。
例如動態庫libhello.so在/home/example/lib目錄下:
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/example/lib
(3) 修改/etc/ld.so.conf文件,把庫所在的路徑加到文件末尾,並執行ldconfig刷新。這樣,加入的目錄下的所有庫文件都可見。
當靜態庫和動態庫同名時, gcc命令將優先使用動態庫。
讀者可能忘記了以上所用到的gcc編譯參數的意義,這裏作簡單介紹:
-fPIC 生成與位置無關的代碼,這樣庫就可以在任何位置被鏈接和裝載。
雖然linux下大多數函數都默認將頭文件放到/usr/include目錄下,而庫文件放到/usr/lib下,但並不是所有的情況都是這樣。在Linux下使用C語言開發應用程序時,完全不使用第三方函數庫的情況是比較少的,通常來將都需要藉助一個或多個函數庫的支持才能夠完成相應的功能。正因爲如此,gcc在編譯的時候必須讓編譯器知道如何來查找所需要的頭文件和庫文件。Gcc採用搜索目錄的方法來查找所需要的文件,-I選項可以向gcc的頭文件搜索路徑中添加新的目錄。例如在/home/david/include目錄下有編譯的時候所需要的頭文件,爲了能夠讓gcc順利的找到他們,就可以使用-I選項:
# gcc david.c –I /home/david/include –o david
同樣,如果使用了不在標準位置的庫文件,那麼可以通過-L選項向gcc的庫文件搜索路徑中添加新的路徑,例如在/home/david/lib目錄下有編譯的時候所需要的庫文件,爲了能夠讓gcc順利的找到他們,就可以使用-L選項:
# gcc david.c –L /home/david/lib –ldavid –o david
這裏解釋一下-l選項,它指示gcc去連接庫文件libdavid.so,linux下的庫文件在命名的時候有個約定,那就是以lib開頭,所有的庫文件都遵循了這個規範,因此用-l選項指定連接的庫文件時就可以省略lib三個字符了。
2.A tutorial for C/C++ programming on Linux