【问题标题】:C/GCC: dlopen() without needing dlsym()C/GCC: dlopen() 不需要 dlsym()
【发布时间】:2013-09-12 06:33:44
【问题描述】:

我可以使用 dlopen() 和 RTLD_NOW 延迟加载共享库。但是一旦库被动态加载,我仍然需要使用 dlsym 单独加载每个符号。

由于我的库包含大量 API,我不想为所有 API 调用 dlsym。有什么方法可以使 API 的工作方式与正常的加载时链接相同(您只需调用 API 而无需 dlsym)?

【问题讨论】:

  • 你的意思是不需要打电话给dlsym()明确
  • 是的,我只需要动态加载库。来自应用程序的 API 调用应该正常工作 - 我不想重写代码以包含每个 API 的 dlsym()。
  • 我将其取消标记为重复,因为 Linux 的共享库语义与 Windows 的共享库语义完全不同;在 Windows 上可能的东西在 Linux 上不一定是可能的,反之亦然。 (对于好奇,ELFPE 可执行图像格式之间的区别在于这里的控制。)
  • stackoverflow.com/a/47221988/841108 是一个几乎重复的问题的答案

标签: c linux gcc linker


【解决方案1】:

您可能正在寻找 RTLD_GLOBAL。

从您链接到的页面[1]:

RTLD_GLOBAL
      The symbols defined by this library will be made available for
      symbol resolution of subsequently loaded libraries.

通过使用它,您应该能够围绕您的 API 创建一个不需要使用 dlsym() 的“包装器”库,从而减少所需的 dlsym() 调用总数。这当然提出了一个问题,即维护包装库是否比清理 API 更费力。

[1]http://man7.org/linux/man-pages/man3/dlsym.3.html

【讨论】:

    【解决方案2】:

    正如here 解释的那样,您可以拥有一个包含attribute(constructor) 函数的插件,该函数将许多插件函数注册到主程序提供的一些全局数据结构中(因为插件的构造函数 在dlopen 插件的时间)。所以你可以有dlopen-ed 一个插件,甚至不使用dlsym 一次来检索和使用(许多)插件功能。

    我需要使用 dlsym 单独加载每个符号。

    错了。 dlsym 通过符号(或名称)查找函数(或数据)。函数已经在这里了(因为插件的整个代码段都被dlopen添加到了你的虚拟地址空间中)。

    【讨论】:

      【解决方案3】:

      可能不再相关,但仍然 - 您正在寻找 Windows DLL 导入库的模拟,这些库将为您的代码提供看起来像普通函数但在内部调用 dlopendlsym 的存根。

      Linux 不提供开箱即用的导入库,但您可以手动生成它们,通过一些自定义脚本或使用Implib.so 工具来完全自动地执行此操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-07
        • 1970-01-01
        • 2012-06-01
        • 2015-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多