之前一直對動態庫靜態庫這個概念很模糊,到了快找實習的時候,決定認真地學一遍,畢竟這到了公司之後會經常用到。
下面是我自己學習的一些筆記
簡單地來說(個人的理解,可能有偏差,希望大神指正):
1、在編譯生成二進位制檔案時,動態庫的源**沒有放到二進位制檔案中,編譯時需要告訴編譯器動態庫的路徑
2、在編譯生成二進位制檔案時,靜態庫的源**載入進去一起編譯
靜態庫有個不好的地方,當靜態庫很大時,載入進去就顯得很費時
首先來看一下下面**:
------------平常寫的main.c-------------
#include
#include "add.h"
int main()
int c=add(10,20);
printf("c=%d",c);
------------------函式模組化(即函式體,要製作成庫的.c檔案)add.c------
#include "add.h"
int add(int a,int b) //這裡只有函式的實現,函式的定義放到標頭檔案中
return a+b;
---------------標頭檔案add.h-------------------------------
#ifndef _add_h_ //防止標頭檔案重複定義
#define _add_h_
#include
int add(int a,int b);
#endif
我們來tree一下這3個檔案的位置,其中lib資料夾裡面放的是我們即將做的庫
1)找到函式定義的地方,將.c檔案編譯成.o檔案(.o檔案裡面的是機器語言):
gcc -c add.c -o add.o
2)把.o檔案編譯生成libadd.so(注意lib是字首,add才是庫名,.so是字尾):
gcc -fpic -shared add.o -o libadd.so
也可以一步到位:gcc -fpic -shared add.c -o libadd.so
注意我這裡標頭檔案沒有跟.c檔案放同乙個目錄,所以要指定一下頭檔案的位置gcc -fpic -shared add.o -o libadd.so -i../include (等一下我們講指定的問題)
3)把生成的庫放到/lib下:
4)編譯命令
gcc main.c -o main -iinclude/ -llib/ -ladd
有人可能會文後面的是啥
這裡說明一下:
-i(大寫的i include):告訴編譯器在**找標頭檔案
-l(庫lib):告訴編譯器在**找庫檔案
編譯完後又有個問題
說載入庫檔案時找不到這個庫,這是因為系統預設在$ld_lbrary_path這裡找
我們可以把庫路徑添臨時加進去:
要永久設定則修改檔案 gedit ~/.bashrc 加到變數上去
或者直接把庫複製到~/lib下
這樣執行就沒問題了!!
1)找到函式定義的地方,將.c檔案編譯成.o檔案(.o檔案裡面的是機器語言):
gcc -c add.c -o add.o
2)把.o檔案編譯生成libadd.a(注意不能一步到位,只能從.o製作靜態庫):
ar -rc libadd.a add.a
3)把庫檔案放到與main.c乙個資料夾,編譯
gcc main.c libadd.a -o main -iinclude (因為我的標頭檔案不在乙個地方,所以得指定)
注意:main.c 和libadd.a順序不能調換
靜態庫與動態庫的製作與使用
生成目標檔案 gcc c add.c o add.o gcc c sub.c o sub.o 製作靜態庫 ar rcs libmylib.a add.o sub.o在使用ar工具是時候需要新增引數 rcs gcc main.c l 靜態庫路徑 i 標頭檔案路徑 lmylib 庫名 o main 引數...
Linux下製作動態庫與靜態庫
靜態函式庫 1.這類庫的名字一般是lib a 2.利用靜態函式庫編譯成的檔案比較大,因為整個函式庫的所有資料都會被整合進目標 中,他的優點就顯而易見了,即編譯後的執行程式不需要外部的函式庫支援,因為所有使用的函式都已經被編譯進可執行檔案了。當然這也會成為他的缺點,因為如果靜態函式庫改變了,那麼你的程...
Linux下靜態庫與動態庫的製作
二者的不同點在於 被載入的時刻不同。靜態庫在程式編譯時會被連線到目標 中,程式執行時將不再需要該靜態庫,因此體積較大 動態庫在程式編譯時並不會被連線到目標 中,而是在程式執行是才被載入,因此在程式執行時還需要動態庫存在,因此 體積較小。現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的 都從零開...