linux dlopen手册翻译

news2024/11/24 3:16:06

名称

dlclose, dlopen, dlmopen 打开和关闭一个共享对象

简介

#include <dlfcn.h>
void *dlopen(const char*filename, int flags);
int dlclose(void *handle);

#define _GNU_SOURCE
#include <dlfcn.h>
void *dlmoopen(Lmid_t lmid, const char *filename, int flags);
Link with -Ldl

描述

dlopen

函数dlopen()加载由以空结尾的字符串filename命名的动态共享对象(共享库)文件,并为加载的对象返回一个不透明的“句柄”。此句柄与dlopen API中的其他函数一起使用,例如dlsym(3), dladdr(3), dlinfo(3)和dlclose()

如果filename为NULL,则返回的句柄是主程序的。如果filename包含斜杠(“/”),则将其解释为(相对或绝对)路径名。否则,动态链接器按照如下方式搜索对象(详见ld.so(8)):

  • (仅限ELF)如果调用程序的可执行文件包含DT_RPATH标签,而不包含DT_RUNPATH标签,则搜索DT_RPATH标签中列出的目录。
  • 如果在启动程序时,定义了环境变量LD_LIBRARY_PATH以包含冒号分隔的目录列表,那么将搜索这些目录。(作为一种安全措施,set-user-ID和set-group-ID程序会忽略这个变量。)
  • (仅限ELF)如果调用程序的可执行文件包含DT_RUNPATH标记,则搜索该标记中列出的目录
  • 缓存文件/etc/ld.so.检查缓存(由ldconfig(8)维护),看它是否包含filename的条目。
  • 搜索目录/lib和/usr/lib(按此顺序)。

如果由filename指定的对象依赖于其他共享对象,那么动态链接器也会使用相同的规则自动加载这些对象。(如果这些对象依次具有依赖关系,则此过程可能递归地发生,等等。)

flags中必须包含以下两个值之一:

  • RTLD_LAZY
    执行延迟绑定。仅在引用符号的代码被执行时解析符号。如果符号从未被引用过,那么它就永远不会被解析。(延迟绑定只对函数引用执行;对变量的引用总是在加载共享对象时立即绑定。)从glibc 2.1.1开始,这个标志被LD_BIND_NOW环境变量的影响所覆盖。

  • RTLD_NOW
    如果指定了该值,或者将环境变量LD_BIND_NOW设置为非空字符串,则在dlopen()返回之前解析共享对象中所有未定义的符号。如果不能这样做,则返回一个错误。

以下0个或多个值也可以在标志中为or:

  • RTLD_GLOBAL
    此共享对象定义的符号将用于随后加载的共享对象的符号解析。

  • RTLD_LOCAL
    这与RTLD_GLOBAL相反,如果两个标志都没有指定,则为默认值。在此共享对象中定义的符号不能用于解析随后加载的共享对象中的引用。

  • RTLD_NODELETE
    在dlclose()期间不要卸载共享对象。因此,如果稍后使用dlopen()重新加载对象,则不会重新初始化对象的静态变量。

  • RTLD_NOLOAD
    不要加载共享对象。这可以用来测试对象是否已经是常驻对象(如果不是,dlopen()返回NULL,或者
    对象的句柄(如果它是驻留的)。此标志还可用于提升已加载的共享对象上的标志。例如,一个先前用RTLD_LOCAL加载的共享对象可以用RTLD_NOLOAD | RTLD_GLOBAL重新打开。

  • RTLD_DEEPBIND
    将此共享对象中符号的查找范围置于全局作用域之前。这意味着自包含对象将优先使用自己的符号,而不是已经加载的对象中包含的具有相同名称的全局符号。

如果filename为NULL,则返回的句柄是主程序的。当给定给dlsym()时,这个句柄会在主程序中搜索一个符号,然后是在程序启动时加载的所有共享对象,然后是由dlopen()加载的带有RTLD_GLOBAL标志的所有共享对象.

共享对象中的外部引用使用该对象的依赖列表中的共享对象和先前使用RTLD_GLOBAL标志打开的任何其他对象来解析。如果可执行文件与标志“-rdynamic”(或,同上,“–export-dynamic”)链接,则可执行文件中的全局符号也将用于解析动态加载的共享对象中的引用。

如果使用dlopen()再次加载相同的共享对象,则返回相同的对象句柄。动态链接器维护对象句柄的引用计数,因此,在dlclose()被调用的次数与dlopen()成功调用的次数相等之前,动态加载的共享对象不会被释放。任何初始化返回(见下文)只调用一次。但是,随后的dlopen()调用使用RTLD_NOW加载相同的共享对象可能会强制对先前使用RTLD_LAZY加载的共享对象进行符号解析。

如果 dlopen() 因为任意原因失败了,则他会返回NULL

返回值

如果成功,dlopen()和dlmopen()将为加载的库返回一个非null句柄。如果出现错误(文件找不到、不可读、格式错误或在加载过程中导致错误),这些函数将返回NULL。

如果成功,dlclose()返回0;如果出现错误,它将返回一个非零值。

这些函数的错误可以使用dlerror(3)进行诊断。

版本

dlopen()和dlclose()在glibc 2.0及更高版本中存在。dlmopen()首次出现在glibc 2.3.4中。

属性

有关本节中使用的术语的解释,请参见attributes(7)。

接口属性
dlopen(), dlmopen(), dlclose()线程安全MT-Safe

CONFORMING TO

POSIX.1-2001 描述了 dlclose() 和 dlopen(). dlmopen() 函数是 GNU 的扩展.
RTLD_NOLOAD, RTLD_NODELETE 和 RTLD_DEEPBIND 标志是 GNU 的扩展; 其中前面的两个也存在于 Solaris 中.

dlmopen() 和命名空间

  • 链接映射列表为动态链接器解析符号定义了一个独立的命名空间。在名称空间内,依赖的共享对象根据通常的规则隐式加载,符号引用也同样根据通常的规则解析,但是这种解析仅限于(显式和隐式)加载到名称空间的对象所提供的定义。

  • dlmopen()函数允许对象加载隔离——能够在新的名称空间中加载共享对象,而不会将应用程序的其余部分暴露给新对象提供的符号。注意,使用RTLD_LOCAL标志是不够的,因为它会阻止共享对象的符号被任何其他共享对象使用。在某些情况下,我们可能希望使动态加载的共享对象提供的符号对(一部分)其他共享对象可用,而不将这些符号暴露给整个应用程序。这可以通过使用单独的命名空间和RTLD_GLOBAL标志来实现。

  • dlmopen()函数还可用于提供比RTLD_LOCAL标志更好的隔离。特别是,如果共享对象是另一个共享对象的RTLD_GLOBAL的依赖,那么用RTLD_LOCAL加载的共享对象可能会被提升为RTLD_GLOBAL。因此,RTLD_LOCAL不足以隔离加载的共享对象,除非在显式控制所有共享对象依赖的情况下(不常见)。

  • glibc的实现最大支持16个命名空间.

初始化和结束函数

  • 共享对象可以使用__attribute__((构造函数))和__attribute__((析构函数))函数属性导出函数。构造函数在dlopen()返回之前执行,析构函数在dlclose()返回之前执行。共享对象可以导出多个构造函数和析构函数,并且可以将优先级与每个函数关联起来,以确定它们执行的顺序。请参阅gcc信息页(在“函数属性”下)了解更多信息。
  • (部分地)实现相同结果的旧方法是通过使用链接器可识别的两个特殊符号:_init和_fini。如果动态加载的共享对象导出一个名为_init()的例程,那么该代码将在加载共享对象之后,在dlopen()返回之前执行。如果共享对象导出名为_fini()的例程,则在对象卸载之前调用该例程。在这种情况下,必须避免链接到系统启动文件,其中包含这些文件的默认版本;这可以通过使用gcc(1) -nostartfiles命令行选项来完成。
  • 现在不赞成使用_init和_fini,而支持前面提到的构造函数和析构函数,它们的优点之一是允许定义多个初始化和结束函数。
  • 自glibc 2.2.3起,atexit(3)可用于注册一个退出处理程序,该处理程序在卸载共享对象时自动调用。

历史

  • 这些函数是派生自SunOS的 dlopen API的一部分.

BUG

与glibc 2.24一样,在调用dlmopen()时指定RTLD_GLOBAL标志会产生错误。此外,在调用dlopen()时指定RTLD_GLOBAL会导致程序崩溃(SIGSEGV),如果调用是从加载在名称空间中而不是初始名称空间中的任何对象进行的。

例子

下面的程序加载(glibc)数学库,查找cos(3)函数的地址,并输出cos(2.0)。下面是构建和运行该程序的测试示例:
程序源码

// dlopen_demo.c
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <gnu/lib-names.h>  /* Defines LIBM_SO (which will be a string such as "libm.so.6") */
int main(void)
{
    void *handle;
    double (*cosine)(double);
    char *error;

    handle = dlopen(LIBM_SO, RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        exit(EXIT_FAILURE);
    }

    dlerror();    /* Clear any existing error */

    cosine = (double (*)(double)) dlsym(handle, "cos");

/* 根据ISO C标准,在函数指针和'void *'之间进行强制转换,如上所述,会产生未定义的结果。
POSIX.1-2001和POSIX.1-2008接受了这种状态,并提出了以下解决方案:

           *(void **) (&cosine) = dlsym(handle, "cos");

       这种(笨拙的)强制转换符合ISO C标准,并将避免任何编译器警告。
       POSIX.1-2008的2013年技术勘误表1改进了这一问题,要求符合标准的实现支持将'void *'转换为函数指针。
       然而,一些编译器(例如,带有'-pedantic'选项的gcc)可能会抱怨这个程序中使用的强制转换。 */

    error = dlerror();
    if (error != NULL) {
        fprintf(stderr, "%s\n", error);
        exit(EXIT_FAILURE);
    }

    printf("%f\n", (*cosine)(2.0));
    dlclose(handle);
    exit(EXIT_SUCCESS);
}

编译和运行该程序

cc dlopen_demo.c -ldl
./a.out
打印结果:
-0.416147

在这里插入图片描述

SEE ALSO

ld(1), ldd(1), pldd(1), dl_iterate_phdr(3), dladdr(3), dlerror(3), dlinfo(3), dlsym(3), rtld-audit(7), ld.so(8), ldconfig(8)
gcc 信息页, ld信息页

版本记录

本页是Linux手册页项目5.10版的一部分。项目的描述、有关报告错误的信息以及本页的最新版本,可以在https://www.kernel.org/doc/man-pages/上找到

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++ Primer Plus习题】12.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream> #include "Stack.h"…

磁电偶极子天线学习1 一种60GHz 宽带圆极化口径耦合磁电偶极子天线阵列

摘要&#xff1a; 一种新型的圆极化口径耦合天线被提出。这种圆极化磁电偶极子天线由刻蚀在短路基片集成波导的一部分的宽臂上&#xff0c;并且很容易被集成基片。在工作频段内实现了宽于28.8%的阻抗带宽和宽带3-dB的25.9%的轴比和的增益。此外&#xff0c;因为圆极化辐射由两个…

稀有卡牌手游【植物大战僵尸】源码

稀有卡牌手游【植物大战僵尸】完整代码&#xff0c;画面精美&#xff0c;非常好玩。代码下载

机器学习1——手把手教你用Python跑一个线性回归模型

目录 一、前期准备 1.Scikit-learn 2.matplotlib 二、机器学习过程 三、代码框架 四、完整代码 1.导入所需库 2.准备训练数据 3.喂入训练数据 4.结果预测 5.输出模型中的w与b值 6.可视化 7.传入不规则数据 一、前期准备 在机器学习中我们使用Python居多&…

基于OMS构建OceanBase容灾双活架构的实践

在实际生产环境中&#xff0c;对于关键业务&#xff0c;往往会有容灾双活的需求。除了OceanBase提供的主备库能力&#xff0c;通过官方工具OMS也可以实现容灾双活架构。目前&#xff0c;通过OMS实现的双活架构仅支持OceanBase数据库之间的数据同步。 要通过OMS实现双活架构&am…

使用Node-API进行线程安全开发

一、Node-API线程安全机制概述 Node-API线程安全开发主要用于异步多线程之间共享和调用场景中使用&#xff0c;以避免出现竞争条件或死锁。 1、适用场景 异步计算&#xff1a;如果需要进行耗时的计算或IO操作&#xff0c;可以创建一个线程安全函数&#xff0c;将计算或IO操作放…

C#程序 Debugger,Release都没问题,但是,打包安装后:System.FormatException: 输入字符串的格式不正确

前言&#xff1a; 这是个问题解决&#xff0c;我们先谈问题&#xff1a; 这个问题不会再本地的调试机器上出现&#xff0c;但是&#xff0c;出现在你部署&#xff0c;或者说安装到其他的机器&#xff08;通过VS构建安装项目来做&#xff09; C#程序 Debugger&#xff0c;Relea…

javascript的模块化

1. 无模块化 script标签引入js文件&#xff0c;相互罗列&#xff0c;但是被依赖的放在前面&#xff0c;否则使用就会报错。如下&#xff1a; <script src"jquery.js"></script><script src"jquery_scroller.js"></script><scr…

Linux block_device gendisk和hd_struct到底是个啥关系

本文的源码版本是Linux 5.15版本&#xff0c;有图有真相&#xff1a; 1.先从块设备驱动说起 安卓平台有一个非常典型和重要的块设备驱动&#xff1a;zram&#xff0c;我们来看一下zram这个块设备驱动加载初始化和swapon的逻辑&#xff0c;完整梳理完这个逻辑将对Linux块设备驱…

.NET 一款用于解密web.config配置的工具

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

位运算:带带孩子吧,孩子很强的!

快速进制 在聊到位运算之前&#xff0c;不妨先简单过一遍二进制的东西。熟悉二进制和十进制的快速转换确实是掌握位运算的基础&#xff0c;因为位运算直接在二进制位上进行操作。如果不熟悉二进制表示&#xff0c;很难直观理解位运算的效果。 这里主要涉及二进制和十进制之间…

蓝桥杯嵌入式国三备赛经验分享

1 学习STM32入门视频 向大家推荐一套宝藏级别的视频&#xff1a;【STM32入门教程-2023版 细致讲解 中文字幕】 如果已经比过蓝桥杯单片机或学习过单片机相关课程的同学&#xff0c;你们可以尝试不需要STM32套件进行学习。如果没有学过单片机相关课程的同学&#xff0c;可以买…

直击智博会,supOS加快发展新质生产力,赋能全球工厂数字化转型

9月6日&#xff0c;第十四届智慧城市与智能经济博览会&#xff08;以下简称智博会&#xff09;开幕主题活动在宁波举办。本届智博会着重围绕“数字赋能新型工业化”主题&#xff0c;设置开幕活动、展览展示和前瞻研讨、产数合作、赛事赋能、开放活动等4大板块活动&#xff0c;旨…

全球AI产品Top100排行榜

Web Top50的榜单里&#xff0c;AIGC类型的应用占比52%&#xff0c;遥遥领先。AIGC类型包括图像、视频、音乐、语音等的内容生成和编辑。音乐生成应用Suno在过去六个月中的排名跃升最为显著&#xff0c;从第36位上升至第5位。排名第二大类是通用对话/AI聊天/角色扮演类型的应用&…

银河麒麟系统开机自动进入指定账户(如:root)桌面

目录 1. 需求的提出 2. 机器环境说明 3. 解决方法 4. 附加说明 1. 需求的提出 编写好的软件在客户的装有银河麒麟操作系统的机器上运行&#xff0c;但有些操作必须用root权限才能操作&#xff0c;如&#xff1a;打开串口。Linux下的普通账户打开串口时提示权限不足。在普通…

【HarmonyOS NEXT】实现截图功能

【HarmonyOS NEXT】实现截图功能 【需求】 实现&#xff1a;实现点击截图按钮&#xff0c;实现对页面/组件的截图 【步骤】 编写页面UI Entry Component struct Screenshot {BuildergetSnapContent() {Column() {Image().width(100%).objectFit(ImageFit.Auto).borderRadi…

C++入门(06)安装QT并快速测试体验一个简单的C++GUI项目

文章目录 1. 清华镜像源下载2. 安装3. 开始菜单上的 QT 工具4. 打开 Qt Creator5. 简单的 GUI C 项目5.1 打开 Qt Creator 并创建新项目5.2 设计界面5.3 添加按钮的点击事件5.4 编译并运行项目 6. 信号和槽&#xff08;Signals and Slots&#xff09; 这里用到了C类与对象的很多…

网络协议详解

目录 1.认识网络协议 2网络协议的设计 2.1网络通信的问题 2.2网络协议的分层设计 软件分层与网络分层 3.OSI七层网络模型 各层次的介绍如下 4.TCP/IP 五层协议 各层次说明 各层次所解决的问题 5.网络和操作系统之间的关系 单主机下 多主机下 6.重新理解网络协议 …

【鸿蒙HarmonyOS NEXT】页面之间相互传递参数

【鸿蒙HarmonyOS NEXT】页面之间相互传递参数 一、环境说明二、页面之间相互传参 一、环境说明 DevEco Studio 版本&#xff1a; API版本&#xff1a;以12为主 二、页面之间相互传参 说明&#xff1a; 页面间的导航可以通过页面路由router模块来实现。页面路由模块根据页…

kubernetes微服务基础及类型

目录 1 什么是微服务 2 微服务的类型 3 ipvs模式 ipvs模式配置方式 4 微服务类型详解 4.1 ClusterIP 4.2 ClusterIP中的特殊模式headless 4.3 nodeport 4.4 metalLB配合loadbalance实现发布IP 1 什么是微服务 用控制器来完成集群的工作负载&#xff0c;那么应用如何暴漏出去&…