如何确定是否已加载so文件?

时间:2014-12-08 12:17:13

标签: c linux windows dll shared-libraries

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

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

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

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

Linux下是否有类似GetModuleHandle的功能?

3 个答案:

答案 0 :(得分:3)

您实际上可以使用dlopen来检查RTLD_NOLOAD标志:

  

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

答案 1 :(得分:3)

  

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

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

考虑一个多线程程序,你在线程1中询问上面的问题(并得到肯定答案),就像线程2调用dlclose(a_so_handle)并卸载a.so一样。

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

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

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

  

但我仍然想在运行时知道这样的加载状态。

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

答案 2 :(得分:0)

您可以使用 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)中有一个简单的例子。