2

我想要 dlopen() 特定目录中的每个共享库。为了做到这一点,
检索linux的库搜索路径的最干净的方法是什么。或者是否有更快的方法在该路径中找到特定目录?
posix会更好。

4

2 回答 2

7

POSIX 不支持在共享库搜索路径上查找目录的机制(LD_LIBRARY_PATH例如,它不强制要求 ),因此任何解决方案本质上都是特定于平台的。

Linux 存在一些问题,因为要使用的值可能基于环境变量/etc/ld.so.conf中的内容以及任何运行时值;LD_LIBRARY_PATH其他系统也存在类似的问题。默认位置也因系统而异——/lib通常/usr/lib用于 32 位 Linux 机器,但至少在一些 64 位机器上使用/lib64/usr/lib64但是,其他平台将其他位置用于 64 位软件。例如,Solaris 使用/lib/sparcv9and /usr/lib/sparcv9,例如(尽管文档提到/lib/64and /usr/lib/64,它们是sparcv9目录的符号链接)。Solaris 也有环境变量LD_LIBRARY_PATH_64LD_LIBRARY_PATH_32. HP-UX 和 AIX 传统上使用LD_LIBRARY_PATH--SHLIB_PATH和之外的其他变量LIBPATH, IIRC——尽管我相信 AIX 现在也使用LD_LIBRARY_PATH了。而且,在 Solaris 上,用于配置共享库的工具是“crle”(配置运行时链接环境),类似的工具/etc/ld.so.conf/var/ld/ld.configor /var/ld/64/ld.config。当然,共享库的扩展名也各不相同(.so.sl.dylib.bundle等)。

因此,您的解决方案将是特定于平台的。您需要确定默认位置、要读取的环境变量、要读取的配置文件以及相关的文件扩展名。鉴于这些,那么它主要是一个 SMOP - 简单的编程问题:

  • 对于任何来源命名的每个目录:
    • 打开相关子目录 ( opendir())
      • 依次读取每个文件名 ( readdir())
      • 在相关文件的路径上使用dlopen()
      • 做任何与你相关的分析。
      • 采用dlclose()
    • 采用closedir()

另请参阅下面评论中的注释......完整的主题适度地充满了平台之间的差异。

于 2010-11-21T01:35:04.473 回答
1

我不确定是否有可能做到这一点并且是便携的。由于这个问题是关于 Linux 的,因此可移植性可能不是最重要的。然后我不明白 POSIX 约束。你能澄清一下吗?

您可能必须实现 中详述的搜索功能man 8 ld.so,其中包括扫描 /etc/ld.so.conf LD_LIBRARY_PATH,或者/lib/ld.so为您做您想做的事情并解析输出。一个不完全漂亮的命令行可能是:

export LD_PRELOAD=THISLIBRARYSODOESNOTEXIST
strace -s 4096 /bin/true 2>&1 | sed -n 's/^open("\([^"]*\)\/THISLIBRARYSODOESNOTEXIST".*$/\1\/YOURSUBDIRHERE/gp'
unset LD_PRELOAD

然后,您可以使用 POSIX 调用opendir(3)readdir(3).

于 2010-11-20T20:40:23.167 回答