Linux 使用dlopen()动态加载共享对象

Linux 使用dlopen()动态加载共享对象,linux,x11,dlopen,binutils,Linux,X11,Dlopen,Binutils,我正在开发一个普通的X11应用程序 默认情况下,我的应用程序只需要libX11.so和标准的gcc C和math libs。 该应用程序可以扩展Xfixes、Xrender和ALSA音响系统的功能。 但是,这些(Xfixes、Xrender和ALSA)功能是可选的 为了实现此行为,我使用运行时加载,即libXfixes、libXrender和libasound应该是dlopen()的 因此,该应用程序可以在没有此类库的情况下运行 现在我的问题是: What library names shoul

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

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

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

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

现在我的问题是:

What library names should I use when calling dlopen()?  
我已经注意到,不同发行版的内容有所不同。
例如,在openSUSE 11上,它们的名称如下:

  • libXfixes.so
  • libXrender.so
  • 利巴松
然而,在Ubuntu上,名称附带了一个版本号,如下所示:

  • libXfixes.so.3
  • libXrender.so.1
  • libasound.so.2
因此,在Ubuntu上尝试打开“libXfixes.So”会失败,尽管lib显然存在。 它只是附带了一个版本号。那么我的应用程序应该如何处理这个问题呢?
我是否应该让我的应用程序先手动扫描/usr/lib/以查看我们有哪些lib,然后选择一个合适的lib?还是有人有更好的主意

谢谢各位


Andy

根据我所学,您只需
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”,例如。

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

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

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


无论如何,您都不希望加载具有不同编号的版本,因为编号的更改表明API存在重大差异。

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