Lesson10 Linux 庫的創建和使用

一、 庫的介紹: 

1.  庫的概念:

     事先已經編譯好的代碼,經過編譯後可以直接調⽤的⽂件。

     本質上來說是⼀種可執⾏代碼的⼆進制形式,可以被操作系統載⼊內存執⾏。

2.  系統庫:/usr/lib、/usr/lib64

3.  庫文件名:lib + 庫名 + 後綴(.a爲靜態庫;.so爲動態庫)

二、 靜態庫與動態庫:

1.  靜態庫:

     靜態庫的代碼在編譯時就已經拷⻉到應⽤程序中。

     當有多個程序同時引⽤⼀個靜態庫函數時,內存中將會生成該函數的多個副本。

     完全拷⻉,⼀旦連接成功,靜態庫就不再需要了。

     程序代碼體積⼤。

2.  動態庫:

     在程序內留下⼀個標記,指明當程序執⾏時, ⾸先必須要載⼊這些庫。

     在程序開始運⾏後調⽤庫函數時才被載⼊,被調⽤函數在內存中只有⼀個副本。

     程序代碼體積⼩。

三、 靜態庫的創建和使用: 

創建步驟:

  • 在頭⽂件(.h)中聲明靜態庫所導出的函數
  • 在源⽂件(.c)中實現靜態庫所導出的函數
  • 編譯源⽂件,⽣成⽬標⽂件(.o)
  • 通過命令 ar 將⽬標⽂件加⼊到靜態庫中
  • 將靜態庫拷⻉到系統默認的存放庫的路徑(/usr/local/lib、/usr/local/include),或指定的路徑下

使用命令:

  • gcc [源文件] -o [可執行文件名] -I[頭文件路徑] -L[靜態庫路徑] -l[靜態庫名]
  • -l :指示編譯器,裝載的函數庫,系統默認的路徑(/usr/lib、/usr/lib64)
  • -L:指定庫所在的路徑
  • -I :指定頭文件所在的路徑

示例及詳解:

1.  頭文件與源文件的編寫:共 5 個文件。

     

  other1.h

#ifndef OTHER1_H
#define OTHER1_H

#include <stdio.h>

void welcome();

#endif

  other1.c 

#include "other1.h"

void welcome(){
        printf("Welcome to MyProject!\n");
}

  other2.h

#ifndef OTHER2_H
#define OTHER2_H

#include <stdio.h>

int add(int, int);
int sub(int, int);

#endif

  other2.c

#include "other2.h"

int add(int x,int y){
        return x+y;
}

int sub(int x, int y){
        return x-y;
}

   app.c

#include "other1.h"
#include "other2.h"

void main(){
        int a=15, b=3,c;
        printf("test in app\n");
        welcome();
        c=add(a,b);
        printf("%d + %d = %d\n",a,b,c);
        c=sub(a,b);
        printf("%d - %d = %d\n",a,b,c);
}

 示例:此結構下編譯 3 個 c 文件,生成可執行程序 app

 

2.  編譯源文件:生成目標文件 .o 

gcc -c other1.c -o other1.o
gcc -c other2.c -o other2.o

     

3.  加入到靜態庫:

ar rcs libother1.a other1.o
ar rcs libother2.a other2.o

 

 示例:此結構下編譯 app.c 文件 

gcc app.c -o app -I./ -L./ -lother1 -lother2 

  

 4.  組織項目:

     include 存放頭文件、lib 存放庫文件、src 存放源代碼。

      

    

    示例:此結構下編譯 app.c 文件

gcc app.c -o app -Iinclude -Llib -lother1 -lother2

5.  加入系統默認存放庫的路徑: 

 將頭文件和庫文件拷貝到 /usr/local 對應目錄下

cp include/* /usr/local/include
cp lib/* /usr/local/lib

調用系統庫編譯文件

gcc app.c -o app -lother1 -lother2

 

四、動態庫的創建和使用:

創建步驟:

  • 在頭⽂件(.h)中聲明動態庫所導出的函數
  • 在源⽂件(.c)中實現動態庫所導出的函數
  • 編譯源⽂件,⽣成與位置⽆關的⽬標⽂件 (.o)
  • 創建動態庫
  • 鏈接動態庫

使用命令:

  • 方式一:gcc [源⽂件] -L [動態庫路徑] -l [動態庫名] -I [頭⽂件路徑] -o [可執⾏⽂件]
  • 方式二:gcc [源⽂件] -I [頭⽂件路徑] [完整庫⽂件名] -o [可執⾏⽂件]

示例及詳解:

1.  編寫頭文件與源文件:與上例靜態庫中的文件相同。

     

2.  編譯源文件並生成與位置無關的目標文件:

gcc -fPIC *.c -I ../include -c

  

3.  創建動態庫:

gcc -shared -o liblinux_test.so *.o

  

mv liblinux_test.so ../lib

  

  利用方式二進行鏈接編譯代碼:

#注意給定的爲絕對路徑
gcc app.c -I include $(pwd)/lib/liblinux_test.so -o app

  

4.  鏈接動態庫: 

LD_LIBRARY_PATH:指定除默認路徑外查找動態庫的路徑,該路徑在默認路徑前進⾏查找。

  • export LD_LIBRARY_PATH=[⾃定義動態庫路徑],起到臨時作⽤
  • 配置環境變量 LD_LIBRARY_PATH,修改文件 ~/.bash_profile 或 ~/.bashrc 或 /etc/profile 或 /etc/bashrc 
  • 直接將動態庫拷貝⾄/usr/lib等系統⽬錄下(可⾏但強烈不推薦)
  • 將動態庫的絕對路徑寫⼊/etc/ld.so.conf⽂件,使⽤ldconfig命令更新(推薦使用)

利用方式一鏈接編譯代碼:

 gcc app.c -Llib -llinux_test -I include -o app

  此時直接運行會報錯,輸入 ldd app 提示找不到動態庫的位置,解決方法如下:

  

  ①設置臨時環境變量: export LD_LIBRARY_PATH=$(pwd)/lib

  

  ②配置環境變量: 編輯上述任意文件,添加語句 export LD_LIBRARY_PATH=/myCode/c/linux_about_lib/dynamic/lib 。

  ③加入系統庫:本文不做演示。

  ④將絕對路徑寫⼊ /etc/ld.so.conf :vim /etc/ld.so.conf

      

      完成後進入 /etc/ 文件夾,輸入 ldconfig 更新,並可找到目錄:

      

      成功運行文件

      

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