linux下靜態庫與共享庫的製作與使用

linux程序設計第四版

庫:預先編譯好的方法/函數的集合

.c文件編譯成.o文件,再將.o文件的方法放入庫文件

存放庫文件的標準路徑 /usr/lib 用戶安裝的  /lib  系統本身的

所有的頭文件.h存放在 usr/include

命令在 /usr/bin  /bin

 

比如:

list.h  聲明

list.c  實現  編譯生成  list.o  鏈接到main裏面   每個人使用都要list.c文件編譯  如果多次就會重複多次

靜態庫命名規則 :  libmylist.a       共享庫:liblist.so

.查看程序使用了哪些共享庫  ldd  main(main爲程序名字)

使用庫的意義

省去了每一次編譯的過程,提高了程序生成的速度,避免重複做無用的事情

隱藏我們自己代碼的實現,對代碼形成一種保護

靜態庫

 

靜態庫的創建與使用
add.c

#include "my.h"
int add(int x,int y)
{
    return x+y;    
}


max.c

#include "my.h"
int max(int x ,int y)
{
    return x>y ? x:y;    
}    


my.h

int max(int x,int y);
int add(int x,int y);



main.c

#include<stdio.h>
#include<stdlib.h>
#include"my.h"
 
int main()
{
    int a = 3;
    int b = 2;
 
    printf("add=%d\n",add(a,b));
    printf("max=%d\n",max(a,b));
    exit(0);
}

libxx.a lib爲前綴  .a爲擴展名

1.所有.c文件編譯成.o文件

2.打包做出庫,ar  crv libxx.a *.o

ar是建立或修改備存文件的命令,參數c表示建立備存文件,r表示插入備存文件,v表示顯示執行過程。

共享庫 libxx.so  《程序員自我修養》第八章

1.將所有.c文件編譯成.o文件

2.生成共享庫 gcc -shared -fPIC -o libmyfoo.so  *.o/*.c

參數的意義《C專家編程》

shared的意義

-fPIC 作用於編譯階段,告訴編譯器產生與位置無關代碼(Position-Independent Code),則產生的代碼中,沒有絕對地址,全部使用相對地址,故而代碼可以被加載器加載到內存的任意位置,都可以正確的執行

使用庫

gcc -o main main.c -L路徑 -l庫名

沒有指定庫,編譯會失敗,要加路徑和庫名   路徑在標準目錄下不用加 在當前位置要加  -L路徑 -l庫名 

 執行可執行程序時還會調用庫文件(共享庫特點),因此有兩種辦法 改變環境變量LD_LIBRARY_PATH,將路徑爲本地路徑,可以系統會在本地路徑搜索共享庫,或者直接吧共享庫放入標準庫文件目錄下

 

系統的頭文件一般放在/usr/include  系統的庫文件一般放在/usr/lib  /lib  可執行程序 /usr/bin  /bin 

 環境變量 LD_LIBRARY_PATH : 系統搜索標準庫文件的路徑 可在一個終端中指定搜索路徑,指定程序運行時鏈接共享庫的位置

終端關閉後失效,臨時改變LD_LIBRARY_PATH=. ( . 爲當前位置 ,中間不能有空格,此時LD_LIBRARY_PATH爲本地變量,可通過 echo $LD_LIBRARY_PATH 查看)
export LD_LIBRARY_PATH ( 將LD_LIBRARY_PATH 設爲環境變量)
 

共享庫與靜態庫的區別


    靜態庫  裏面的方法會編譯鏈接包含到程序   體積太大  
    共享庫  編譯鏈接,只做標記  沒有包含方法的實現   運行程序時  動態加載(速度較慢),並且裏面方法可以被多個程序共享使用

靜態庫是在生成可執行程序時,將靜態庫的方法包含在了可執行程序中,即刪除靜態庫,​但由於靜態庫方法已經被包含在了可執行程序中,則程序仍可執行,不再依賴於外部靜態庫。

​共享庫是在運行程序時才動態加載庫方法,若刪除共享庫,則程序運行時進行動態加載庫方法時找不見共享庫,程序將無法執行。

靜態庫的運行速度快,但程序體積相對較大,不易版本升級,若升級,則程序需要重新編譯;
共享庫由於運行要動態加載庫文件,則運行速度慢,但程序體積小,方便版本升級,程序不用重新編譯

 

問題

  • 使用什麼命令可以查看某個進程使用了哪些庫

使用ldd main命令

  • 製作共享庫時,-fPIC含義是什麼

       表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的,所以動態載入時是通過代碼拷貝的方式來滿足不同的調用,而不能達到真正的代碼段共享的目的

 

關於gcc的編譯參數:
-fPIC 生成與位置無關的代碼,這樣庫就可以在任何位置被連接和裝載
-shared 代表共享庫
-o 鏈接生成指定名字的庫或程序
-l 指定要鏈接的共享庫
-L 指定共享庫所在路徑

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章