linux动态加载动态链接库—— dlopen()

动态加载动态链接库

  在linux操作系统中,linux提供了加载和处理动态链接库的系统调用函数

函数原型

//函数所在头文件位置
#include <dlfcn.h>

//dlopen以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程
void *dlopen(const char *filename, int flag);

//dlsym通过handle句柄和连接符名称获取函数名或者变量名
void *dlsym(void *handle, const char *symbol);

//当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示没有错误信息。
char *dlerror(void);

//dlclose来卸载打开的库
int dlclose(void *handle);

函数功能

  1. dlopen
    dlopen以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程,该句柄为 ELF 对象的句柄。filename为文件所在目录,若非系统特定目录的动态库,则必须带上目录路径,否则运行时会找不到动态库。flag为打开的模式,RTLD_NOW,它表明动态链接器将会在调用 dlopen 时完成所有必要的再定位。 RTLD_LAZY,它只在需要时执行再定位。
  2. dlsym
    通过调用 dlsym 来识别这个handle句柄对象内的符号的地址了。可以返回动态库中的函数或全局变量。symbol为想要调用的函数名称或变量名。
  3. dlerror
    如果调用dlopen、dlsym API 时发生了错误,dlerror 函数返回一个字符串,在没有错误发生时返回 NULL。
  4. dlclose
    dlclose 来通知操作系统不再需要句柄和对象引用了,任何通过已关闭的对象的 dlsym 解析的符号都将不再可用。

实例

my.c
int number = 100;

int add(int a, int b)
{
    return (a + b);
}
main.c
#include <dlfcn.h>
#include <stdio.h>

typedef int (*func)(int , int );

int main()
{
    void *handle;
    int *num = NULL;
    int sum = 0;
    func p;

    handle = dlopen("./my.so", RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "%s", dlerror()); // 打开my.so失败时,输出错误信息到stderr
        return -1;
    }

    p = (func)dlsym(handle, "add");	// 从my.so中获取到add函数
    num = (int*)dlsym(handle, "number");	// 从my.so获取到number变量

    sum = p(10, *num); // 执行add函数

    printf("sum = %d\n", sum);

    dlclose(handle); // 关闭handle

    return 0;
}
makefile
all:
	gcc -fPIC -shared my.c -o my.so
	gcc -rdynamic -o main main.c -ldl
	./main

使用gcc -fPIC -shared my.c -o my.so生成动态库
  -fPIC 表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
  -shared 生成动态库
gcc -rdynamic -o main main.c -ldl
   -rdynamic 用来通知链接器将所有符号添加到动态符号表中,目的是能够通过使用 dlopen 来实现向后跟踪。
   -ldl 表明一定要将 dllib 链接于该程序,不然编译器会报dlopen、dlsym、dlerror、dlclose等找不到

输出

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值