天天看點

linux共享庫的動态加載

linux c中打開庫檔案,用的是dlopen函數,該函數主要是加載庫中的符号,

第一個參數:是共享庫的名稱,注意如果要引用本檔案夾内的庫檔案,加./檔案名

第二個參數:

RTLD_NOW:在dlopen傳回前,對于動态庫中的未定義的符号不執行解析(隻對函數引用有效,對于變量引用總是立即解析)。

RTLD_NOW: 需要在dlopen傳回前,解析出所有未定義符号,如果解析不出來,在dlopen會傳回NULL,錯誤為:: undefined symbol: xxxx.......

void*dlsym(void*handle,constchar*symbol)

根據動态連結庫操作句柄與符号,傳回符号對應的位址

handle:由dlopen打開動态連結庫後傳回的指針;

symbol:要求擷取的函數或全局變量的名稱。

void* 指向函數的位址,供調用使用。

用法:

1.建立一個目錄, mycal

mkdir mycal

2.在mycal目錄下建立兩個目錄 modules, src

3.在modules建立兩個檔案 cal.h,cal.c

cal.h:

#ifndef __CAL_H__

#define __CAL_H__

int add(int a, int b);

int sub(int a, int b);

int dive(int a, int b);

int mul(int a, int b);

#endif

cal.c:

#include "cal.h"

int add(int a, int b)

{

    return a + b;

}

int sub(int a, int b)

{

    return a - b;

}

int mul(int a, int b)

{

    a * b;

}

int dive(int a, int b)

{

    return a / b;

}

制作共享庫:

gcc -c -fPIC cal.c

gcc -shared -Wl,-soname,libmycal.so.1 -o libmycal.so.1.10 cal.o

soname是一個符号連結的名字,隻包含共享庫的主版本号,想要深入了解相關細節,請查閱相關資料,這裡就不多說了

注意:-Wl,-soname,libmycal.so.1 之間沒有空格

4.在src目錄下建立 main.c檔案

main.c:

#include <stdio.h>

#include "../modules/cal.h"

#include <dlfcn.h>

int main(void)

{

    int (*add)(int a, int b);

    void *handle = dlopen("../modules/libmycal.so.1.10", RTLD_LAZY);

    if (handle == NULL) {

        printf("Failed load library\n"); 

        return -1;

    }

    char *err = dlerror();

    if (err != NULL) {

        printf("%s\n", err); 

        return -1;

    }

    add = dlsym(handle, "add");

    err = dlerror();

    if (err != NULL) {

        printf("%s\n", err); 

        dlclose(handle);

        return -1;

    }

    printf("%d", add(5, 3));

    dlclose(handle);

    return 0;

}

編譯檔案:

gcc -o main main.c -ldl

注意:-ldl選項在最後

至此共享庫的動态加載算是完成了,謝謝大家!!!

繼續閱讀