首页 > 其他分享 >dlopen 加载一个共享so库资源

dlopen 加载一个共享so库资源

时间:2024-12-02 21:57:13浏览次数:10  
标签:符号 void so dlopen 共享 RTLD 加载

一.先生成一个共享so库文件

// example.c
#include <stdio.h>

void hello() {
    printf("Hello from the shared library!\n");
}

void test(int a)
{
    printf("Test from the shared library! parameter is %d\n",a);
}

用命令生成so库文件

#编译共享库:

gcc -shared -fPIC -o libexample.so example.c

就会在目录下生成一个libexample.so文件

二.在主方法中执行该动态so库调用方法

int main() {

    // ---- 加载动态so库文件
    /**
     *  void* dlopen(const char* filename, int flag);
        filename:要加载的共享库的路径(可以是绝对路径或相对路径)。如果值为 NULL,表示加载主程序(通常不使用该选项)。
        flag:用于指定加载共享库的方式,可以是以下的一个或多个标志的组合:
        RTLD_LAZY:延迟加载,即只有在调用符号时才进行解析。
        RTLD_NOW:立即加载,即在加载时解析所有符号。
        RTLD_GLOBAL:使库中的符号在其他共享库中可见(默认是 RTLD_LOCAL,即符号仅在当前库内部可见)。
        RTLD_LOCAL:符号只对当前共享库可见。
     */
    void* handle = dlopen("/demo_c/libexample.so", RTLD_LAZY);
    /**
     * 返回值:
        成功时,dlopen 返回一个非 NULL 的指针,指向已加载的共享库的句柄。
        失败时,返回 NULL,并且可以使用 dlerror() 函数获取错误信息。
     */
    if (!handle)
    {
        // 如果加载失败,输出错误信息
        fprintf(stderr, "Error loading library: %s\n", dlerror());
    }
    else
    {
        printf("libexample.so 库已经被成功加载!\n");
    }

    // 获取库中的函数
    void (*hello)();
    void (*test)(int);

    // dlsym():用于查找共享库中某个符号(函数或变量)。
    // 它返回一个指向该符号的指针,可以将其转换为合适的函数指针类型。
    hello = dlsym(handle,"hello");
    test = dlsym(handle,"test");

    // 检查函数是否找到
    if (!hello)
    {
        fprintf(stderr, "Error finding symbol: %s\n", dlerror());
        dlclose(handle);
    }

    // 调用函数
    hello();
    test(10);

    // 关闭已加载的共享库,释放资源。
    dlclose(handle);

    // ---------------------
}

输出以下内容

libexample.so 库已经被成功加载!
Hello from the shared library!   -- 说明加载了libexample.so库文件中的 hello方法
Test from the shared library! parameter is 10 -- 说明加载了libexample.so库文件中的 test方法

三.说明

  1. dlopen 的基本用法                                                                                                   void* dlopen(const char* filename, int flag);                                                                     参数:                                                                ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        filename:要加载的共享库的路径(可以是绝对路径或相对路径)。如果值为 NULL,表示加载主程序(通常不使用该选项)。​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        flag:用于指定加载共享库的方式,可以是以下的一个或多个标志的组合:

    RTLD_LAZY:延迟加载,即只有在调用符号时才进行解析。
    RTLD_NOW:立即加载,即在加载时解析所有符号。
    RTLD_GLOBAL:使库中的符号在其他共享库中可见(默认是 RTLD_LOCAL,即符号仅在当前库内部可见)。
    RTLD_LOCAL:符号只对当前共享库可见。
    返回值:       成功时,dlopen 返回一个非 NULL 的指针,指向已加载的共享库的句柄。                失败时,返回 NULL,并且可以使用 dlerror() 函数获取错误信息。
  2. dlsym():用于查找共享库中某个符号(函数或变量)。它返回一个指向该符号的指针,可以将其转换为合适的函数指针类型。

    void* dlsym(void* handle, const char* symbol);
  3. dlclose():关闭已加载的共享库,释放资源。

    int dlclose(void* handle);

四.小结

  • 使用 dlopen 动态加载共享库。
  • 使用 dlsym 获取符号地址(如函数指针)。
  • 使用 dlclose 卸载共享库,释放资源。

dlopen 和相关函数常用于插件系统、动态扩展等场景。

标签:符号,void,so,dlopen,共享,RTLD,加载
From: https://blog.csdn.net/wydaicls/article/details/144166520

相关文章

  • 使用vue3-json-excel插件数据过长生成的数据变为科学计数法
    存在的问题:借用vue3-json-excel插件导出的xls的tagID这一项数据过长出现科学技术法。方法1.网上给出的办法是将长数字转换为字符串。我的数据tagID这个数据接口返回来的本就是字符串。所以改方法不行......
  • Gfx.dll:支撑Microsoft Office运行的重要组件
    在探讨MicrosoftOffice这一全球广泛使用的办公软件套件时,我们往往会聚焦于其强大的文字处理、电子表格、演示文稿制作等功能。然而,在这些光鲜亮丽的用户界面和丰富功能背后,有一个不太为人知的但至关重要的组件——Gfx.dll,它在支撑Office软件的正常运行中扮演着不可或缺的角色......
  • 编译OpenCV——jetson嵌入式平台
    jetson嵌入式平台的系统为:ubuntu20.04aarch64不再研究Ubuntux64上交叉编译ubuntuaarch64的OpenCV库,因为无法识别到arm的GTK导致编译不进去,最终imshow时会报如下错误:modules/highgui/src/window.cpp:611:error:(-2)Thefunctionisnotimplemented.Rebuildthelibraryw......
  • WPF+MVVM案例实战与特效(三十一)- 封装一个加载动画的自定义控件
    文章目录1、案例效果2、案例实现1、资源与文件创建2、自定义控件封装3、自定义控件使用4、总结1、案例效果2、案例实现在开发WPF应用程序时,我们常常需要一个灵活的加载动画控件,该控件可以根据窗口的大小自动调整其内部元素(如图片、边框和文本)的尺寸,并......
  • 永嘉VINKA-LED显示驱动数显驱动芯片VK1640 SOP28适用于血氧仪,温控仪LED驱动
    产品品牌:永嘉微电/VINKA产品型号:VK1640封装形式:SOP28概述VK1640是一种数码管或点阵LED驱动控制专用芯片,内部集成有数据锁存器、LED驱动等电路。SEG脚接LED阳极,GRID脚接LED阴极,可支持8SEGx16GRID的点阵LED显示。适用于小型LED显示屏驱动。采用SOP28的封装形式。LJQ3501特......
  • 面对api-ms-win-core-console-l1-2-0.dll丢失怎么处理?dll找不到的解决方法
    api-ms-win-core-console-l1-2-0.dll是Windows操作系统中的一个动态链接库文件,它属于Microsoft的WindowsAPI集的一部分。这个DLL文件主要负责提供与控制台相关的功能支持。当用户尝试运行某些应用程序时遇到此文件丢失或损坏的错误提示,通常会导致程序无法正常启动。......
  • 深入源代码,探秘Tomcat类加载机制:为何颠覆双亲委派原则(1)?
    1.什么是双亲委派 jvm启动后会通过其类装载子系统,去硬盘上找xxx.class文件,找到之后,会直接将xxx这个类装载到java虚拟机中,这个过程叫做类的加载。而类的加载过程中就涉及到了双亲委派。 类加载机制的双亲委派(ParentDelegationModel)是Java中的一种类加载策略,旨在确保Java......
  • 什么是ETL过程(Extract, Transform, Load) 提取 转换 加载
    ‌什么是ETL过程(Extract,Transform,Load)提取转换加载ETL(Extract,Transform,Load)‌是数据集成领域中的一种关键技术,广泛应用于数据仓库、大数据处理和现代数据分析体系中。ETL过程涉及从不同的数据源提取数据、对数据进行转换和清洗,最后将处理后的数据加载到目标系统或数......
  • Financial - Brinson绩效归因实例
    Brinson绩效归因(BrinsonPerformanceAttribution)是投资管理中用来分析投资组合相对于基准(如市场指数)表现差异的一种方法。它由GaryP.Brinson、L.RandolphHood和GilbertL.Beebower在1986年提出,主要通过将投资组合的超额收益分解为几个不同的因素来理解和评估投资决策的有......
  • 不会前端也能写官网?没问题,Devbox+Cursor 带你起飞
    大家平时都是怎么给自己的产品开发官方网站的?是不是先在本地配置好环境,然后使用IDE写代码,写完代码后部署到服务器生成预览链接,团队协作成员再打开浏览器访问,然后你再修改,再部署,再访问,再修改,再部署,再访问...今天给你们分享一个丝滑的方案,让你告别繁琐的本地环境配置,告别反复沟......