【问题标题】:How to determine if a so file has been loaded or not?如何判断一个so文件是否已经加载?
【发布时间】:2014-12-08 12:17:13
【问题描述】:

我有两个共享库:a.so 和 b.so。

a.so 必须在 b.so 加载之前加载。而且,a.so 可能由其他模块加载,而不是由我加载。

所以,我想在调用dlopen("b.so", ...)之前确定是否已经加载了a.so。

在 Windows 下,我可以使用 GetModuleHandle("a.dll") 通过检查返回值来确定。即如果返回值不为null,则a.dll已经加载;否则还没有加载。

Linux下有类似GetModuleHandle的功能吗?

【问题讨论】:

  • 为什么不是你在加载a.so时自己设置的布尔变量?
  • @JoachimPileborg,a.so 可能被其他模块加载,而不是我。
  • 那为什么不干脆让b.so依赖a.so,这样系统会在b.so加载的时候自动加载a.so呢?
  • @JoachimPileborg,这确实是一个解决方案。但是我还是想知道一个so在运行时的加载状态。

标签: c linux windows dll shared-libraries


【解决方案1】:

您实际上可以使用dlopen 来检查这一点,并带有RTLD_NOLOAD 标志:

不要加载库。这可以用来测试库是否已经常驻(dlopen() 如果不是,则返回 NULL,如果是常驻,则返回库的句柄)。

【讨论】:

  • 非常感谢,约阿希姆。这正是我正在寻找的。​​span>
  • @xmllmx 虽然这正确回答了原始问题,但问题本身表明您可能做错了什么。
【解决方案2】:

在调用 dlopen 之前确定是否已加载 a.so

这几乎肯定是错误的做法(即你问错了问题)。

考虑一个多线程程序,您在线程 1 中提出上述问题(并收到肯定的答案),就像线程 2 调用 dlclose(a_so_handle)s 并卸载 a.so

相反,您可能会在线程 1 中得到否定答案,就像线程 2 完成 dlopen("a.so", ...) 并加载它一样。

正确的做法是做dlopen("a.so", ...); dlopen("b.so", ...);

如果 a.so 已经加载,第一个 dlopen 将简单地增加其引用计数。如果它尚未加载,它将是。

但我还是想知道一个so在运行时的加载状态。

您无法可靠地了解该状态。您得到的答案是:a.so 当前可能已加载,也可能未加载。

【讨论】:

  • 顺便说一句,这在 Windows 上也是如此。
【解决方案3】:

您可以使用 dl_iterate_phdr

#define _GNU_SOURCE
#include <link.h>

    int dl_iterate_phdr(
             int (*callback) (struct dl_phdr_info *info,
                              size_t size, void *data),
             void *data);

回调采用具有 dlpi_name 成员的 struct dl_phdr_info。 dl_iterate_phdr(3) 中有一个简单的示例。

【讨论】:

    猜你喜欢
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多