动态库的动态链接、打开、调用,使用dlopen、dlsym和dlclose

动态库的动态链接、打开、调用,使用dlopen、dlsym和dlclose


 为了使程序方便扩展,具备通用性,可以采用插件形式。采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形基本的操作方法,式加载进来,这就是所谓的插件。Unix, linux和windows都有提供加载和处理动态链接库的系统调用,非常简单;

基本的操作方法

  • 动态链接库如何被加载进来?
  • 动态链接库如何被调用


举例说明

1.创建一个libCalculator.c文件,有四个很简单的函数,如下

#include <stdio.h>

int add(int a, int b)
{
    return (a + b);
}

int subtract(int a, int b)
{
    return (a - b);
}

int multiply(int a, int b)
{
    return (a * b);
}

int divide(int a, int b)
{
    return (a / b);
}

2.使用gcc命令将此文件生成.so动态库

gcc -fPIC -shared libCalculator.c -o libCalculator.so

3.创建一个控制台项目来使用并调用这个库

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

//定义函数指针
typedef int (*CalculatorFuncPointer)(int, int);

int main(int argc, const char * argv[]) {
    
    //动态库地址
    char *dlib_path = "/Users/VictorZhang/Desktop/Repos/libCalculator.so";
    
    //链接并打开动态库
    void *handle = dlopen(dlib_path, RTLD_GLOBAL | RTLD_NOW);
    if (handle == NULL) {
        fprintf(stderr, "%s\n", dlerror());
    } else {
        
        //获取add函数
        //注意:函数指针接收的add函数有几个参数和什么返回类型要一致
        CalculatorFuncPointer add_func = dlsym(handle, "add");
        int add_ret = add_func(10, 20);
        printf("add function result : %d \n", add_ret);
        
        
        //获取subtract函数
        //注意:函数指针接收的subtract函数有几个参数和什么返回类型要一致
        CalculatorFuncPointer subtract_func = dlsym(handle, "subtract");
        int subtract_ret = subtract_func(10, 20);
        printf("subtract function result : %d \n", subtract_ret);
        
        
        //获取multiply函数
        //注意:函数指针接收的multiply函数有几个参数和什么返回类型要一致
        CalculatorFuncPointer multiply_func = dlsym(handle, "multiply");
        int multiply_ret = multiply_func(10, 20);
        printf("multiply function result : %d \n", multiply_ret);
        
        
        //获取divide函数
        //注意:函数指针接收的divide函数有几个参数和什么返回类型要一致
        CalculatorFuncPointer divide_func = dlsym(handle, "divide");
        int divide_ret = divide_func(10, 2);
        printf("divide function result : %d \n", divide_ret);

        
        dlclose(handle);
    }
    return 0;
}

说明:

  1. 我们的所有操作的相关函数都在#include <dlfcn.h>头文件里
  2. dlopen函数负责动态链接并打开指定动态库,第一个参数是动态库地址,第二个参数如下解释;
  3. dlsym函数负责动态加载符号(函数),第一个参数是句柄(由dlopen时返回的),第二个参数就是给定的函数名称
  4. dlclose函数负责关闭指定句柄的动态库,当该库的使用计数为0时,就会被卸载


dlopen的第二个参数表示解析方式:

RTLD_LAZY   表示使用时才解析函数引用

RTLD_NOW   立即解析函数引用

RTLD_GLOBAL  动态库中定义的符号可被其后打开的其它库解析

RTLD_LOCAL    与RTLD_GLOBAL相反,动态库中定义的符号不能被其打开的其它库重定位,如果没有明确指明,默认是RTLD_LOCAL

RTLD_NODELETE    在dlclose()期间不卸载库,并且在以后使用dlopen()重新加载库时不初始化库中的静态变量。这个flag不是POSIX-2001标准。

RTLD_NOLOAD     不加载库。可用于测试库是否已加载(dlopen()返回NULL说明未加载,否则说明已加载),也可用于改变已加载库的flag,如:先前加载库的flag为RTLD_LOCAL,用dlopen(RTLD_NOLOAD|RTLD_GLOBAL)后flag将变成RTLD_GLOBAL。这个flag不是POSIX-2001标准



超简单的吧,是不是~~~



  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux中,Qt Creator是一个强大的集成开发环境,用于开发跨平台的应用程序。在使用Qt Creator创建和调用动态时,需要经过以下几个步骤: 1. 首先,在Qt Creator中新建一个工程。选择“Dynamic Library”作为项目类型。 2. 在工程文件中,定义需要暴露给其他程序使用的函数和类。可以在.h头文件中声明函数和类的口,并在.cpp源文件中实现相应的功能。 3. 编译生成动态文件。在Qt Creator中,可以点击“构建”按钮编译和链生成动态文件。生成的动态文件一般以.so(shared object)为扩展名。 4. 创建一个新的可执行程序项目,并引用该动态。在新的项目中,需要在.pro文件中添加对动态的依赖关系。例如,可以使用LIBS += -L/path/to/library -lmylibrary来指定动态的路径和名称。 5. 在可执行程序中调用动态中的函数或类。在主函数或其他需要使用动态的地方,可以直调用动态中定义的函数或类,实现相应的功能。 值得注意的是,动态调用中还需要注意以下几点: 1. 在调用动态函数时,需要先加载动态。可以使用dlopen函数加载动态文件,并使用dlsym函数获取需要调用的函数指针。 2. 调用动态中的函数时,需要根据函数的参数类型进行适当的类型转换。因为动态函数的参数类型可能与调用者的类型不完全匹配。 3. 在完成动态使用后,需要使用dlclose函数关闭对动态的引用,释放相关资源。 总结来说,使用Qt Creator在Linux中创建和调用动态需要进行项目的设置、编译生成动态文件,然后在其他项目中引用动态调用其中定义的函数或类。同时,还需要注意动态的加载和关闭过程,以确保正确使用动态功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值