Linux应用编程-动态加载动态库 dlopen dlsym dlclose

        使用so动态库时,可以在编译时链接动态库,也可以在代码运行时动态加载so库。本文主要介绍如何动态加载so库。

常用的函数主要有dlopen,dlysm,dlclose,dlerror。

一、函数介绍

1、dlopen函数

void * dlopen( const char * pathname, int mode)

  • 功能:打开动态库返回句柄
  • pathname:so动态库的路径,可以是相对路径
  • mode:选项配置
常用mode功能
RTLD_LAZY在dlopen返回前,对于动态库中存在的未定义的变量(如外部变量extern,也可以是函数)不执行解析,就是不解析这个变量的地址
RTLD_NOW

在dlopen返回前,解析出每个未定义变量的地址,如果解析不出来,在dlopen会返回NULL,错误为:

: undefined symbol: xxxx.......

其他mode详解参考https://www.cnblogs.com/ho966/p/17366207.html
  • 返回值:动态库的句柄

2、dlsym函数

void *dlsym(void *handle, const char *symbol)

  • 功能:根据给定的符号名称查找对应的符号地址,例如函数名会返回函数地址
  • handle:dlopen打开的动态库的句柄
  • symbol:需要查找的符号名称
  • 返回值:symbol符号地址

3、dlclose函数

int dlclose (void *__handle)

  • 功能:关闭__handle句柄

4、dlerror函数

char *dlerror (void)

  • 功能:检查上次调用是否成功,成功返回NULL,失败返回出错信息

二、实例

1、编译生成so库

#include <stdio.h>

/* 加 */
int cal_add(int a,int b)
{
    return (a + b);
}

/* 减 */
int cal_sub(int a, int b)
{
    return (a - b);
}

/* 乘 */
int cal_mul(int a, int b)
{
    return (a * b);
}

/* 除 */
int cal_div(int a, int b)
{
    return (a / b);
}

编译,生成自定义的 libcalculate.so 库

$ gcc -fPIC -shared calculate.c -o libcalculate.so

2、动态加载so库

动态加载 libcalculate.so 库,获取 cal_add 加法函数并调用

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

typedef int (*FUNC)(int, int);
int main(int argc, char* argv[])
{
    void *lib;
    FUNC lib_func = NULL;
    int temp1, temp2, result;

    if (argc != 3) {
        printf("param error!!!");
		return -1;
    }

    temp1 = strtol(argv[1], NULL, 10);
    temp2 = strtol(argv[2], NULL, 10);

    /* 打开动态链接库 */
    lib = dlopen("./libcalculate.so", RTLD_LAZY);
	if (lib == NULL) {
		printf("%s dlopen failed: %s\n", "libcalculate.so", dlerror());
    }

    /* 获取库函数 */
    lib_func = dlsym(lib, "cal_add");       
    if (!lib_func) {
        printf("can't find module symbol: %s\n", dlerror());
    }
    
    /* 调用库函数 */
	result = lib_func(temp1, temp2);
    printf("result: %d\n", result);

    return 0;
}

编译应用程序, 需要加上"-ldl"库,才能调用dlopen、dlclose等函数

$ gcc -o test_app main.c -ldl                #编译生成 test_app 可执行文件

3、测试结果

./test_app 3 8                                #运行应用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值