【问题标题】:Dynamic loading of shared objects using dlopen()使用 dlopen() 动态加载共享对象
【发布时间】:2010-05-13 13:36:01
【问题描述】:

我正在开发一个普通的 X11 应用程序。

默认情况下,我的应用只需要 libX11.so 以及标准的 gcc C 和数学库。 该应用程序可以通过 Xfixes、Xrender 和 ALSA 声音系统扩展功能。 但是,这些(Xfixes、Xrender 和 ALSA)功能是可选的。

为了实现这种行为,我使用了运行时加载,即 libXfixes、libXrender 和 libasound 应该是 dlopen()ed。

因此,应用程序可以在没有此类库的情况下运行。

现在我的问题:

What library names should I use when calling dlopen()?  

我观察到这些因发行版而异。
例如,在 openSUSE 11 上,它们被命名为:

  • libXfixes.so
  • libXrender.so
  • libasound.so

然而,在 Ubuntu 上,名称附有版本号,如下所示:

  • libXfixes.so.3
  • libXrender.so.1
  • libasound.so.2

所以在 Ubuntu 上尝试打开“libXfixes.so”会失败,尽管 lib 显然在那里。 它只是附加了一个版本号。那么我的应用应该如何处理呢?
我是否应该让我的应用程序首先手动扫描 /usr/lib/ 以查看我们拥有哪些库,然后选择合适的库?或者有人有更好的主意吗?

谢谢大家,

安迪

【问题讨论】:

标签: linux x11 dlopen binutils


【解决方案1】:

您应该使用库的 SONAME 进行 dlopen。您可以使用readelf -d [libname] 看到这一点。

例如,在我的一台 Fedora Linux 机器上,C 库的 SONAME 是 libc.so.6。

不保证从 .so 名称到 .so.6 名称的符号链接。这些符号链接仅在编译软件时需要,通常不会安装在没有开发包的系统上。

无论如何,您都不希望最终加载具有不同编号的版本,因为编号的变化表明主要的 API 差异。

【讨论】:

  • 大多数库都是向后兼容的,这意味着具有更高 soname 的库应该可以工作。假设你编写了一个 dlopens libc.so.6 的程序。然后 libc 开发人员进行了重大更新并发布了libc.so.7。现在您的程序将不必要地中断,因为 soname 不匹配。
  • @BjörnLindqvist:不,大多数库向后兼容。你从哪里得到这个想法的?如果它们兼容,则它们不会更改主要版本号。 GNU libc 已经在 6 上运行了很长时间了。
  • 您可以包含 并使用提供的宏来加载各种 glibc 共享库。其他包可能会做类似的事情来提供要加载的库的名称。有关示例,请参见“man dlopen”。
【解决方案2】:

据我所知,您只需 dlopen()(例如)“libXfixes.so”,无论如何,这很可能是指向最新文件“libXfixes.so.3”的符号链接,其方式与此类似:

$ file /usr/lib/libalpm.so
/usr/lib/libalpm.so: symbolic link to `libalpm.so.4.0.3'

对我的“/usr/lib/”的快速概览显示,其中几乎每个库都符号链接到它最新的“.X”编号文件,我相信这也是它在其他发行版上的做法。

仅当您需要特定版本的库时,才明确将版本命名为“libXfixes.so.2”。

【讨论】:

猜你喜欢
  • 2015-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 2018-03-23
相关资源
最近更新 更多