动态库作用举例

1.定义解析

符号地址:

符号地址是指代码中定义的函数、变量或其他标识符的内存地址。在程序编译和链接的过程中,这些符号会被编译器和链接器分配一个具体的内存地址。

每个符号在程序的执行过程中都有一个唯一的地址,用于指示它在内存中的位置。符号的地址由操作系统和链接器负责管理,它在程序运行时将被加载到内存中的相应位置。

符号地址的概念在计算机科学中是与编程和链接密切相关的。每个函数、变量、常量或其他标识符都有一个关联的地址,它表示该标识符在内存中的位置,可以被程序使用来访问和操作相应的数据或执行相应的代码。

在动态链接过程中,符号的地址可能是在程序运行时动态解析和加载的。通过使用函数如
dlsym(),我们可以在运行时获取符号的地址,并根据它来动态调用对应的函数或操作对应的数据。

在总体上,符号地址是指代码中标识符的内存地址,它是程序在运行时与对应数据或代码之间建立联系的重要概念。

dlsym() :

dlsym() 是一个在动态链接库中查找符号地址的函数。它的作用是根据指定的符号名称,在动态链接库中查找该符号的地址,并返回该地址的指针。

dlsym() 函数通常与 dlopen() 函数配合使用,用于在运行时动态加载共享库,并获取库中定义的符号的地址。

使用 dlsym() 函数可以按照以下方式完成符号地址的查找:

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

  • handle 参数是由之前调用 dlopen() 函数返回的共享库句柄,它用于指定要查找的共享库。

  • symbol 参数是一个字符串,表示要查找的符号的名称。
    dlsym() 函数将会在指定的共享库中查找具有指定名称的符号,并返回该符号的地址。如果找不到该符号,dlsym() 将会返回 NULL。

一旦获取到符号的地址,我们可以将其强制转换为相应类型的函数指针,然后通过该函数指针来调用符号所表示的函数。

总而言之,dlsym() 提供了一种在运行时动态查找共享库中符号地址的机制,使得我们可以通过符号名称来获取共享库中定义的符号地址,并在程序中进行相应的动态调用。

共享库作用

比如,许多软件产品在运行时使用共享库来升级压缩包装的 (shrink-wrapped)二进制程序。还有,大多数 Web 服务器都依赖于共享库的动态链接来提供动态内容 。
当使用共享库来升级压缩包装的二进制程序时,下面是一个示例代码:

示例一

示例共享库源代码(upgrade_lib.c)

#include <stdio.h>

void upgrade_function()
{
    printf("Upgrading program functionality...\n");
}

示例程序源代码(main.c):

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

typedef void (*UpgradeFunction)();

int main()
{
    // 动态加载共享库
    void* libHandle = dlopen("./libupgrade.so", RTLD_LAZY);
    if (!libHandle) {
        fprintf(stderr, "Error: Failed to load upgrade library: %s\n", dlerror());
        return 1;
    }
    
    // 获取共享库中的函数指针
    UpgradeFunction upgrade = (UpgradeFunction)dlsym(libHandle, "upgrade_function");
    if (!upgrade) {
        fprintf(stderr, "Error: Failed to find upgrade function in the library: %s\n", dlerror());
        dlclose(libHandle);
        return 1;
    }
  
    // 执行升级功能
    upgrade();
  
    // 关闭共享库
    dlclose(libHandle);
  
    return 0;
}

在上述代码中,我们定义了一个简单的升级函数 upgrade_function(),它会打印一条升级功能的信息。然后,在主程序中,我们使用 dlopen() 函数动态加载名为 “libupgrade.so” 的共享库,并获取其中的升级函数的函数指针。最后,通过调用该函数指针来执行升级功能。

要使用这个示例代码,需要先编译共享库和主程序。使用以下命令来编译:

# 编译共享库
gcc -shared -o libupgrade.so upgrade_lib.c

# 编译主程序
gcc -o my_program main.c -ldl

执行 ./my_program 命令来运行程序,它将加载共享库,调用升级函数,并打印相应的升级信息。

如果要升级功能,只需替换 libupgrade.so 文件,并重新运行程序,它将加载新的共享库并执行新的升级功能。这样可以实现在无需重新编译自身二进制程序的情况下,通过替换共享库来升级程序功能。

UpgradeFunction 是一个用户定义的函数指针类型,用于指向具有特定签名(参数和返回值类型)的函数。

在示例中,我们定义了 typedef void (*UpgradeFunction)();,它表示 UpgradeFunction 是一个函数指针类型,指向一个没有参数并且没有返回值的函数。

dlfcn.h 是一个头文件,它包含了操作系统提供的动态链接库(共享库)相关的函数和宏定义。这些函数和宏定义包括了动态加载共享库、获取符号地址、关闭共享库等操作的声明。

在示例程序中,我们使用 dlopen()、dlsym() 和 dlclose() 函数来操作动态链接库。这些函数都是在 dlfcn.h 头文件中声明的。

通过包含 dlfcn.h 头文件,我们可以在代码中调用这些动态链接库相关的函数,以实现动态加载共享库并获取其中的函数指针,以及在需要时关闭共享库等功能。

在使用 dlsym() 函数获取共享库中的符号地址时,我们将其结果进行强制类型转换为 UpgradeFunction 类型,是为了确保编译器正确解释该地址对应的函数类型。

dlsym() 函数的返回值类型是 void*,即一个指向内存地址的指针。但在我们的示例中,我们定义了 UpgradeFunction 作为一个函数指针类型,用于指向没有参数和返回值的函数。因此,我们需要通过类型强制转换,将 void* 类型的地址转换为 UpgradeFunction 类型的函数指针。

这样做是为了确保编译器正确理解返回的地址是一个函数的地址,并且能够正确处理函数的调用。如果不进行类型转换,编译器可能会给出警告或错误,因为它无法确定返回的地址的类型,并且无法正确验证函数的参数和返回值的匹配情况。

在使用 dlsym() 获取函数指针时,确保强制类型转换的目标类型与实际函数的签名匹配是很重要的。如果类型不匹配,可能导致函数调用时发生错误或未定义的行为。所以,为了确保类型的匹配性和安全性,我们将 dlsym() 的结果转换为 UpgradeFunction 类型。

示例二

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/558133.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

万物皆可计算|下一个风口:近内存计算-2

虽然PIM可以有缓解内存墙的问题&#xff0c;但是PIM设计面临着一系列技术和工程上的挑战&#xff0c;这些挑战直接影响着PIM技术的实用化和广泛应用&#xff1a; 地址翻译与操作映射&#xff1a; 在传统计算机体系结构中&#xff0c;地址空间由操作系统管理和调度&#xff0c;通…

万物皆可计算|下一个风口:近内存计算-1

传统的冯诺依曼架构虽然广泛应用于各类计算系统&#xff0c;但其分离的数据存储与处理单元导致了数据传输瓶颈&#xff0c;特别是在处理内存密集型任务时&#xff0c;CPU或GPU需要频繁地从内存中读取数据进行运算&#xff0c;然后再将结果写回内存&#xff0c;这一过程涉及大量…

Vue3:响应式数据的基本使用(ref、reactive)

一、前言 在Vue3中&#xff0c;如果数据不是响应式数据&#xff0c;当数据的值发生改变时&#xff0c;页面上的数据是不会发生改变的。因此本文主要介绍Vue3中响应式数据的使用&#xff0c;包括ref和reactive的基本使用。 二、ref 1、ref —— 创建基本类型的响应式数据 re…

电大搜题微信公众号:重庆开放大学学子的学习利器

在当今信息化时代&#xff0c;学习已经成为每个人不可或缺的一部分。然而&#xff0c;对于重庆开放大学的学子们来说&#xff0c;由于远程教育的特殊性&#xff0c;他们面临着更大的学习挑战。幸运的是&#xff0c;他们现在可以依靠一款强大的学习利器——电大搜题微信公众号&a…

软考中级网络工程师-2024上岸宝典

1.软考是什么 简单说就是计算机技术 相关的国家级证书考试&#xff0c;想听专业点给大家截一张官网的图&#xff0c;不想听废话直接往下。 同为国家级证书的&#xff1a;注册会计师、法律职业资格证、一级建筑师&#xff0c;证书的价值是比较高的。 很多人都是在求职前或者大…

【面试经典 150 | 二叉树层序遍历】二叉树的右视图

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;层序遍历方法二&#xff1a;深度优先搜索 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于…

全球媒体发稿:海外发稿数字期刊Digital Journal

全球媒体发稿&#xff1a;海外发稿数字期刊Digital Journal ​官网&#xff1a; digitaljournal.com 数字期刊&#xff0c;加拿大知名门户&#xff0c;月访量超过30万。 是一个全球媒体平台和内容合作伙伴&#xff0c;通过捕捉和报道第一&#xff0c;提升新闻周期中的声…

快手本地生活服务商系统怎么操作?

当下&#xff0c;抖音和快手两大短视频巨头都已开始布局本地生活服务&#xff0c;想要在这一板块争得一席之地。而这也很多普通人看到了机遇&#xff0c;选择成为抖音和快手的本地生活服务商&#xff0c;通过将商家引进平台&#xff0c;并向其提供代运营服务&#xff0c;而成功…

工厂数字化系统是自研,还是对外采购

数字化转型在企业中变得越来越普遍&#xff0c;众多数字化项目的增加也引发了自研和采购数字化系统的讨论。自研和采购各有优劣&#xff0c;需要根据企业的实际情况和需求来做出明智的选择。 自研数字化系统 适用情况&#xff1a;重要核心业务、复用率高、需要长期优化迭代的系…

用队列实现栈(力扣第225题)

#include "stdio.h" #include "stdbool.h" #include "string.h" #include "stdlib.h" #include "assert.h"//初始化队列 typedef int QueueDataType;typedef struct queue {QueueDataType val;struct queue* next; }Qnode;t…

符文协议的演变历程:从挑战到创新

在比特币网络长期面临的挑战中&#xff0c;与主流去中心化金融功能的兼容性一直是一大难题。相比之下&#xff0c;以太坊通过ERC-721和ERC-1155代币标准&#xff0c;为NFT和去中心化金融应用提供了支持&#xff0c;而比特币的应用范围却相对有限。然而&#xff0c;近年来&#…

Linux知识点(4)

文章目录 13. 线程13.1 什么是线程13.2 Linux下的线程13.2.1 pthread_create13.2.2 线程为什么高效&#xff1f;13.2.3 线程的优缺点13.2.4 线程异常13.2.5 线程用途 13.4 虚拟地址空间13.5 Linux线程控制13.5.1 POSIX线程库13.5.2 创建线程13.5.3 线程ID及进程地址空间布局13.…

如何构建企业技术架构-解决内部系统连接的问题

随着企业信息化建设的深入&#xff0c;各类管理系统在运营管理中发挥着关键作用。为了实现数据共享、业务流程自动化和决策支持的无缝对接&#xff0c;往往搭建一个高效协同的技术架构至关重要。本文将以人事系统、泛微OA&#xff08;Office Automation&#xff09;及ERP&#…

基于Springboot+Vue的Java项目-网上点餐系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

【御控物联】Java JSON结构转换(4):对象To对象——规则属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、术语解释三、案例之《JSON对象 To JSON对象》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0…

Nginx莫名奇妙返回了404

描述 nginx作为反向代理&#xff0c;代理python的服务&#xff0c;但是通过代理访问服务的时候&#xff0c;报了404的错误。 难受的是客户现场没有查看日志的权限&#xff0c;只有查看配置文件的权限&#xff0c;我们检测了几遍配置文件也没有找到问题&#xff0c;哎~ 问题引…

Python兼职:只需要一台电脑宅在家,轻松实现月入过万!

Python兼职副业 Python是一种简单易学、高效强大的编程语言&#xff0c;正变成越来越多人选择的热门技能。不论你是否有编程基础&#xff0c;在学习Python的道路上&#xff0c;坚持每天投入2小时&#xff0c;你将看到巨大的回报。 学习Python不仅可以为你提供更多就业机会&am…

【情侣博客网站】

效果图 PC端 建塔教程 第一步&#xff1a;下载网站源码&#xff08;在文章下方有下载链接&#xff09; 第二步&#xff1a;上传到服务器或虚拟主机&#xff0c;解压。 第三步&#xff1a;这一步很关键&#xff0c;数据库进行连接&#xff0c;看图 admin/connect.php就是这…

链表带环问题——leetcode环形链表1 2

证明链表带环 链表的带环问题指的是本该指向NULL的最后一个节点指向了之前的节点&#xff0c;导致链表成环&#xff0c;找不到尾结点的情况&#xff0c;那么我们该如何证明链表带环呢&#xff1f; 我们可以类比物理中的追及问题&#xff0c;让快慢指针同时走&#xff0c;两者相…

element-ui form表单自定义label的样式、内容

element-ui form表单自定义label的样式、内容 效果截图 代码 <el-form size"small" :inline"true" label-width"120px"><el-form-item prop"name"><div slot"label"><i style"color: red;"…