linux 動態載入 動態連結程式庫

來源:互聯網
上載者:User

動態庫的顯式調用

顯式調用的含義是代碼出現庫檔案名稱,使用者需要自己去

開啟和管理庫檔案。其要點為:

⑴把dlfcn.h系統標頭檔包含進來

⑵用dlopen函數開啟庫檔案,並指定開啟檔案

dllope的的第一個參數為共用庫的名稱,將會在下面位置尋找指定的共用庫。

   ①環境變數LD_LIBRARY_PATH列出的用分號間隔的所有目錄。

   ②檔案/etc/ld.so.cache中找到的庫的列表,由ldconfig命令重新整理。

   ③目錄usr/lib。

   ④目錄/lib。

   ⑤目前的目錄。

第二個參數為開啟共用庫的方式。有兩個取值

   ①RTLD_NOW:將共用庫中的所有函數載入到記憶體

   ②RTLD_LAZY:會推後共用庫中的函數的載入操作,直到調用dlsym()時方載入某函數

⑶用dlerror()函數測試是否開啟成功,並進行錯誤處理;

⑷用dlsym獲得函數地址,存放在一個函數指標中

⑸用獲得的函數指標進行函數調用。

⑹程式結束時用dlclose關閉開啟的動態庫,防止資源流失。

⑺用ldconfig工具把動態庫的路徑加到系統庫列表中

1、編寫測試檔案

//main.c 測試動態庫顯式調用的程式

#include<dlfcn.h>      //用於動態庫管理的系統標頭檔  

#include "myalib.h"    //要把函數的標頭檔包含進來,否則編譯時間會報錯

int main(int argc,char* argv[])

{

   //聲明對應的函數的函數指標

   void (*pTest)();        

   //載入動態庫

   void *pdlHandle = dlopen("libtest.so", RTLD_LAZY);

   //錯誤處理

        if(pdlHandle == NULL )    {

        printf("Failed load library/n");

        return -1;

    }

    char* pszErr = dlerror();

    if(pszErr != NULL)

    {

        printf("%s/n", pszErr);

        return -1;

    }

    //擷取函數的地址

    pTest = dlsym(pdlHandle, "test");

    pszErr = dlerror();

    if(pszErr != NULL)

    {

        printf("%s/n", pszErr);

        dlclose(pdlHandle);

        return -1;

    }

    //實現函數調用

    (*pTest)();

   //程式結束時關閉動態庫

   dlclose(pdlHandle);

   return 0;  

}

2、編譯測試檔案 使用-ldl選項指明產生的對象模組需要使用共用庫

gcc -o main -ldl main.c

執行完後就產生了一個main檔案

3、執行測試程式

執行 ./main

輸出

    test

    說明成功。

----------------------------------分割------------------------------------------

//say.c

 

#include <stdio.h>

int say(char **str){
        printf("%s/n",str);

}

將say.c 產生共用庫的編譯:
gcc -o dlopen.so -shared say.c

//使用dlopen函數動態載入庫的原始碼

 


#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>

void show_help(char *msg){
        if(msg == NULL){
                printf("Usage:mydlopen dlopen.so say stringtosay/n");
        }else{
                printf("%s/n",msg);
        }
        exit(1);
}
int main(int ac,char ** av){

        if(ac < 3){
                show_help(NULL);
        }
        void *handle;
        //void *pfunc;

        int (*pfunc)(char *str);
        char * filename = av[1];
        char * func = av[2];
        char * word = av[3];
        char * error;
        handle = dlopen(filename,RTLD_LAZY);
        if(!handle){
                printf("Error: handle/n");
                return 1;
        }

        pfunc = (int (*)(char *))dlsym(handle,func);
        if((error=dlerror()) != NULL){
                printf("Error: dlsym/n");
                return 2;
        }
        (*pfunc)(word);

        dlclose(handle);
        return 0;

}

//編譯命令:

gcc -o mydlopen mydlopen.c  -ldl

注意事項:

1.dlsym返回的指標是無類型的,要轉換的指定的函數的類型。
2.使用函數指標時的寫法: (*pfunc)(word); 不能直接寫成 pfunc(word);會段錯誤的
3.C還不支援預設參數,寫show_help時不能給msg以NULL的預設值
3.編譯時間要使用共用庫dl 其中有dlopen dlsynm dlerror dlclose 函數

使用命令:

./mydlopen ./dlopen.so say aaaabbbdddd

------------------------------------分割------------------------------------------

說明:pfunc = (int (*)(char *))dlsym(handle,func);

其中char *是將參數強轉,因為int (*pfunc)(char *str);是這樣定義的。

如果int (*pfunc)(char *str,int number);這樣定義,那麼強轉的時候應該這樣寫:

pfunc = (int (*)(char *,int))dlsym(handle,func);

--------------------------------------分割-----------------------------------------

編譯的時候的說明,比如現在的檔案分類樹如下:

1.work/

2.|--head.h

3.|--main.c

4.|--func.c

5.|--func2.c

這個時候欲將func2.c編譯成動態連結程式庫dlfunc.so,而func2.c中的函數用到了head.h和func.c裡面的變數和函數,這個時候應該使用命令:

gcc -o dlfunc.so -shared func2.c func.c -I./

這樣就產生了dlfunc.so。

然後編譯串連主程式。

gcc -o test main.c -ldl -I./

就行了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.