C語言庫相關知識及簡單庫的製作

庫即二進制形式的目標模塊,使用庫可以很方便對程序進行模塊化設計,

方便對某些固定功能的重複使用,方便對某些功能進行更新。

庫與.c文件關係如下圖:

庫分爲兩種類型,即靜態庫和動態庫;

靜態庫擴展名.a ,庫中封裝的二進制代碼,在鏈接階段被複制到調用模塊中,

調用模塊運行時不再需要靜態庫的支持;

動態庫擴展名.so ,庫中封裝的二進制代碼,在鏈接階段不會複製到調用模塊,

被嵌入到調用模塊中的僅僅是被調用函數在庫中的相對地址,

因此,調用模塊在運行時需要動態庫的支持。

動態庫和靜態庫相比,使用更爲靈活,更常見。

庫的製作:

靜態庫的製作:

第一步:編輯源程序,包括a.c a.h . . .

第二步:源程序編譯成目標文件,gcc -c a.c  --->a.o . . .

第三步:打包目標文件,即把他們做成庫,ar -r libxxx.a a.o b.o c.o . . .

ar命令解釋:

格式:ar   [選項]    靜態庫名    目標文件列表

選項如下:

-r:將目標文件插入到靜態庫,若目標文件已存在,則更新

-q:將目標文件追加到靜態庫的末尾

-d:從靜態庫中刪除指定的目標文件

-t:列表形式顯示靜態庫中的目標文件

-x:將靜態庫展開爲目標文件

動態庫的製作:

第一步:編輯源程序,包括xxx.c xxx.h

第二步:編譯成目標模塊,gcc -fpic -c a.c . . .

-fpic:小模式,代碼量小,速度快,只支持一部分平臺,比如Linux

-fPIC:大模式,代碼量較大,速度較慢,支持所有平臺

第三步:鏈接成庫,gcc -shared a.o . . . -o libxxx.so

庫的使用:

1、直接調用法

gcc main.c libmath.a / gcc main.c libmath.so

2、參數調用法

gcc main.c -lmath -L. //-l庫名    -L庫所在路徑

3、設置環境變量法

靜態庫設置方法:export LIBRARY_PATH=$LIBRARY_PATH:.

動態庫設置方法:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

爲了永久設置環境變量,可將上述語句寫入~/.bashrc

gcc main.c -lmath

動態庫的使用還可以利用Linux中的dl庫實現動態加載

簡單實例如下:

其中add和show是庫中的函數,add 的功能是將兩個數相加,返回結果;show 的功能是 printf 傳進來的數

#include <stdio.h>
#include <dlfcn.h>
#include "math.h"  //動態庫裏的頭文件
#include "show.h"  //動態庫裏的頭文件

typedef int (*operation)(int,int);  //給函數類型 int (*) (int,int) 起別名operation
typedef void (*d_show)(int);

int main()
{
    int a,b;

    void *handle = dlopen("./libmath.so",RTLD_LAZY);  //獲取庫的句柄
    if(handle == NULL)
    {
        printf("%s\n",dlerror());
        return;
    }

    operation add = (operation)dlsym(handle,"add");  //“add”爲庫裏面的函數,執行加法運算,該語句的作用是獲取add函數在庫裏面的地址
    if(add == NULL)
    {
        printf("%s\n",dlerror());
        return;
    }

    d_show show = (d_show)dlsym(handle,"show");
    if(show == NULL)
    {
        printf("%s\n",dlerror());
        return;
    }

    printf("請輸入兩個整數:");
    scanf("%d %d",&a,&b);
    printf("%d + %d = ",a,b);
    show(add(a,b));  //show,add爲本文件的變量,不是庫裏面的函數名

    dlclose(handle);
    return 0;
}

 

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