天天看點

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 個檔案。

Lesson10 Linux 庫的建立和使用

  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

Lesson10 Linux 庫的建立和使用

2.  編譯源檔案:生成目标檔案 .o 

gcc -c other1.c -o other1.o
gcc -c other2.c -o other2.o
           
Lesson10 Linux 庫的建立和使用

3.  加入到靜态庫:

ar rcs libother1.a other1.o
ar rcs libother2.a other2.o
           
Lesson10 Linux 庫的建立和使用

 示例:此結構下編譯 app.c 檔案 

gcc app.c -o app -I./ -L./ -lother1 -lother2 
           
Lesson10 Linux 庫的建立和使用

 4.  組織項目:

     include 存放頭檔案、lib 存放庫檔案、src 存放源代碼。

Lesson10 Linux 庫的建立和使用
Lesson10 Linux 庫的建立和使用

    示例:此結構下編譯 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
           
Lesson10 Linux 庫的建立和使用

四、動态庫的建立和使用:

建立步驟:

  • 在頭⽂件(.h)中聲明動态庫所導出的函數
  • 在源⽂件(.c)中實作動态庫所導出的函數
  • 編譯源⽂件,⽣成與位置⽆關的⽬标⽂件 (.o)
  • 建立動态庫
  • 連結動态庫

使用指令:

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

示例及詳解:

1.  編寫頭檔案與源檔案:與上例靜态庫中的檔案相同。

Lesson10 Linux 庫的建立和使用

2.  編譯源檔案并生成與位置無關的目标檔案:

gcc -fPIC *.c -I ../include -c
           
Lesson10 Linux 庫的建立和使用

3.  建立動态庫:

gcc -shared -o liblinux_test.so *.o
           
Lesson10 Linux 庫的建立和使用
mv liblinux_test.so ../lib
           
Lesson10 Linux 庫的建立和使用

  利用方式二進行連結編譯代碼:

#注意給定的為絕對路徑
gcc app.c -I include $(pwd)/lib/liblinux_test.so -o app
           
Lesson10 Linux 庫的建立和使用

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 提示找不到動态庫的位置,解決方法如下:

Lesson10 Linux 庫的建立和使用

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

Lesson10 Linux 庫的建立和使用

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

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

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

Lesson10 Linux 庫的建立和使用

      完成後進入 /etc/ 檔案夾,輸入 ldconfig 更新,并可找到目錄:

Lesson10 Linux 庫的建立和使用

      成功運作檔案

Lesson10 Linux 庫的建立和使用

繼續閱讀