一、庫函數
- 什麼是庫函數:庫在linux中以二進制的形式存在,在編譯的時候需要鏈接這些庫文件
- 庫函數的作用:庫文件是一些函數的集合,將我們函數的具體內容進行封裝,僅對外提供一個調用的接口,給用戶使用(即用戶不需要知道函數是如何實現的,只需要調用即可)
- 庫分類:
- 1、靜態庫(.a文件): libxxx.a 編譯的時候,把這個函數鏈接到可執行程序裏去,編譯後的可執行文件較大
- 2、動態庫(.so文件):libxxx.so 編譯的時候,沒有將函數體鏈接到可執行程序中,而是把一些符號鏈接起來,在運行的時候再加載對應的函數。
二、庫函數的製作
- 首先先了解一下編譯的過程:
- 分爲 4個 過程
- 預處理 gcc -E hello.c -o hello.i //將宏定義展開、文件包含、刪除部分代碼等
- 編譯 gcc -S hello.i -o hello.s //將C程序翻譯成機器的彙編語言
- 彙編 gcc -c hello.s -o hello.o //編譯、彙編制定的源文件,但是不進行鏈接
- 連接 gcc hello.o -o hello //將.o文件鏈接成一個可執行文件
- 靜態庫的製作:
- 1、首先將需要製作成庫文件的函數編譯一下:
- gcc -c add.c (此時會生成對應的add.o文件)
- 2、將生成的add.o文件封裝到庫文件libmylib.a中
- ar -rcs libmylib.a add.o (ar 指令是專門用於對庫來進行操作的)
- 使用靜態庫來進行編譯(鏈接)程序:
- gcc hello.c -L . -lmylib
- 或者
- gcc hello.c -L . libmylist.a
- 注意:如果不使用-l 指定使用什麼庫文件,而是直接使用的話,需要將該庫文件的路徑一併打出來,如果是在當前文件夾下,則不需要。
- 其中 -L 後跟着庫文件路徑 -l(小寫L)爲庫文件libxxx.a中xxx的名字,若不使用-l則輸入庫文件全稱,如果提示信息缺少頭文件則可以加上-I (大寫i)頭文件路徑
- 動態庫的製作:
- 1、首先將需要製作成庫文件的函數編譯一下:
- gcc -c add.c (此時會生成對應的add.o文件)
- 2、將生成的add.o打包生成一個動態庫
- gcc -shared -fPIC -o libmylib.so add.o (-shared 共享對象文件,-fPIC 作用於編譯階段,告訴編譯器產生與位置無關代碼)
- 使用動態庫來進行編譯(鏈接)程序
- gcc hello.c -o hello -L . -lmylib
- 或者
- gcc hello.c -L . libmylist.so
三、在使用庫函數(鏈接)編譯程序時需要注意的事項
- 在使用動態庫的時候,編譯好後,如果直接運行程序會報錯(原因是查找不到動態庫)
- 解決方法:
- 1、直接將自己的動態庫 移動到 /lib 或者 /usr/lib 中
- 2、修改環境變量 LD_LIBRARY_PATH :
- 通過修改 家目錄下 .bashrc 或者 /etc/profile 來添加動態庫路徑
- 如: export LD_LIBRARY_PATH=/home/gec/lib:$LD_LIBRARY_PATH
- 然後 source .bashrc (使其立即生效)
- 3、通過修改/etc/ld.so.conf(添加的路徑爲最優先路徑)
- 在ld.so.conf 中 添加 /home/gec/lib
- 保存後執行 ldconfig