1. 程式人生 > >Linux動態庫的 靜態載入 和 動態載入 的使用

Linux動態庫的 靜態載入 和 動態載入 的使用

動態庫的靜態載入 

math.c
   #include<stdio.h>
   
   int add(int a,int b)
   {
      return a+b;
   }
show.c 
   #include<stdio.h>
   
   int show(int a)
   {
       printf("兩數之和:%d",a);
   }
    

 編譯成目標模組:
 

gcc -fpic -c math.c  -o math.o                    //自行編寫他們的標頭檔案放在同一目錄下

gcc -fpic -c show.c -o show.o

連結成共享庫

gcc -shared math.o show.o -o libmath.so

libmath.so為動態庫,libxxx    其中 xxx 為動態庫的名字

將動態庫的路徑加到環境變數中

在Linux的目錄終端執行一下程式碼

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

  .  表示當前目錄

在終端執行

gcc main.c libmath.so

生成 a.out 執行./a.out      。完成

動態庫動態載入

動態載入是在程式執行期間載入和解除安裝動態庫

Linux中的dl庫實現庫的動態載入

載入共享庫 ---- dlopen

     filename:給路徑按照路徑載入,給檔名就根據LD_LIBRARY_PATH環境變數去查詢

     flag:載入標誌

        RTLD_LAZY:延遲載入,什麼時候真正使用的時候才載入  

        RTLD_NOW:立即載入

返回值:

    成功返回動態庫的控制代碼,失敗返回NULL

獲取動態庫的的函式地址 ------- dlsym

    handle:動態庫的控制代碼

    symbol:函式名

返回值:

    成功返回函式地址,失敗返回NULL

解除安裝動態庫 -------------dlclose

handle:動態庫的控制代碼

獲取出錯資訊 --------- dlerror

返回錯誤字串

dmain.c
#include<stdio.h>
#include<dlfcn.h>

typedef int(*PFUNC_CALL)(int,int);
typedef int(*PFUNC_SHOW)(int);        //給函式指標定義一個別名   PFUNC_SHOW = int(*)(int)

int main()
{

    void *handle = dlopen("./libmath.so",RTLD_LAZY);  //載入動態庫
        if(handle==NULL)
        {
            printf("dlopen失敗:%s\n",dlerror());
            return -1;
        }
    //獲取函式地址
    PFUNC_CALL add = (PFUNC_CALL)dlsym(handle,"add");
    if(add==NULL)
    {
        printf("dlsym失敗:%s\n",dlerror());
        return -1;
    }


    int(*show)(int)= dlsym(handle,"show");              //int(*show)(int) = PFUNC_SHOW
    if(add==NULL)                                       // 函式原型  int show(int)
    {
        printf("dlsym失敗:%s\n",dlerror());
        return -1;
    }

    show(add(9,5));

    dlclose(handle);
    return 0;
}

在終端上編譯生成  a.out 檔案

gcc dmain.c libmath.so  -ldl