動態庫與靜態庫詳細說明

動態庫:

生成:

1:gcc test_b.c -fPIC -shared -o libtest.so/*生成動態庫  可以不用先生成.o文件,直接做成一個動態庫。
-shared該選項指定生成動態連接庫(讓連接器生成T類型的導出符號表,有時候也生成弱連接W類型的導出符號),不用該標誌外部程序無法連接。相當於一個可執行文件
-fPIC:表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的*/
2:gcc -fPIC -c test.c //也可以先生成.o文件,然後再做成動態庫
gcc -shared -o libtest.so test.o

鏈接:

1:gcc test.c -L. -ltest//-L 後面接路徑 ,比如 -L . 表示庫在當前路徑下,test是動態庫的名字,這種方式有可能出現運行程序時找不到庫的問題。
2:gcc test.c ./libtest.so //直接加路徑,指定庫名鏈接,這種方式不用擔心運行程序時找不到庫的問題。

鏈接動態庫時,系統有個動態鏈接器,程序運行的時候時通過動態鏈接器去找動態庫,如果動態鏈接器尋找的路徑中沒有我們要的動態庫,就算程序編譯過了也運行不了,這時候有幾種解決辦法;

  1. 修改環境變量, 通過環境變量LD_LIBRARY_PATH把當前庫目錄添加到共享庫的搜索路徑
  2. 編輯/etc/ld.so.conf文件,將庫文件所在路徑加進去,運行ldconfig -v,該命令會重建/etc/ld.so.cache緩存文件, 動態鏈接器就從 這個緩存中搜索共享庫
  3. 將動態庫複製到/lib 或 /usr/lib 或 /usr/local/lib 系統都能找到
  4. 編譯的時候將動態庫的路徑寫死 gcc test.c -L. -lahelp -Wl,-rpath,/home -Wl,-rpath,/home表示-rpath /home是由gcc傳遞給鏈接器的選項

動態庫特點總結:

  1. 動態庫運行時再鏈接,很容易出現編譯過了運行找不到庫的問題。
  2. 可以實現進程之間的資源共享。(因此動態庫也稱爲共享庫)
  3. 將一些程序升級變得簡單。
  4. 程序運行時還需要動態庫存在
  5. 動態庫的大小比靜態庫要大得多

靜態庫:

生成:

gcc -c test.c -o test.o
ar rsc libtest.a test.o  //先要生成.o文件 在把所有的.o文件 打包成一個靜態庫

ar命令參數說明
r:在庫中插入模塊(替換)。當插入的模塊名已經在庫中存在,則替換同名的模塊。如果若干模塊中有一個模塊//在庫中不存在,ar顯示一個錯誤消息,並不替換其他同名模塊。默認的情況下,新的成員增加在庫的結尾處,可以//使用其他任選項來改變增加的位置。
c:創建一個庫。不管庫是否存在,都將創建。
s:創建目標文件索引,這在創建較大的庫時能加快時間。(補充:如果不需要創建索引,可改成大寫S參數;如果。a文件缺少索引,可以使用ranlib命令添加

鏈接:

1:gcc test.c -L. -ltest;//-L 後面接路徑 ,比如 -L . 表示庫在當前路徑下,test是靜態庫的名字。
2:gcc test.c ./libtest.a;//接加路徑,指定庫名鏈接

靜態庫特點總結:

  1. 靜態庫編譯時鏈接。
  2. 程序在運行時與函數庫再無瓜葛,移植方便。
  3. 只要編譯過了,就不用擔心運行問題。
  4. 浪費空間和資源,因爲所有相關的目標文件與牽涉到的函數庫被鏈接合成一個可執行文件,會導致可執行文件會佔用比較大的空間。
  5. 是靜態庫對程序的更新、部署和發佈頁會帶來麻煩。如果靜態庫liba.lib更新了,所以使用它的應用程序都需要重新編譯、發佈給用戶(對於玩家來說,可能是一個很小的改動,卻導致整個程序重新下載,全量更新)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章