我想要 dlopen() 特定目录中的每个共享库。为了做到这一点,
检索linux的库搜索路径的最干净的方法是什么。或者是否有更快的方法在该路径中找到特定目录?
posix会更好。
2 回答
POSIX 不支持在共享库搜索路径上查找目录的机制(LD_LIBRARY_PATH
例如,它不强制要求 ),因此任何解决方案本质上都是特定于平台的。
Linux 存在一些问题,因为要使用的值可能基于环境变量/etc/ld.so.conf
中的内容以及任何运行时值;LD_LIBRARY_PATH
其他系统也存在类似的问题。默认位置也因系统而异——/lib
通常/usr/lib
用于 32 位 Linux 机器,但至少在一些 64 位机器上使用/lib64
。/usr/lib64
但是,其他平台将其他位置用于 64 位软件。例如,Solaris 使用/lib/sparcv9
and /usr/lib/sparcv9
,例如(尽管文档提到/lib/64
and /usr/lib/64
,它们是sparcv9
目录的符号链接)。Solaris 也有环境变量LD_LIBRARY_PATH_64
和LD_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.config
or /var/ld/64/ld.config
。当然,共享库的扩展名也各不相同(.so
、.sl
、.dylib
、.bundle
等)。
因此,您的解决方案将是特定于平台的。您需要确定默认位置、要读取的环境变量、要读取的配置文件以及相关的文件扩展名。鉴于这些,那么它主要是一个 SMOP - 简单的编程问题:
- 对于任何来源命名的每个目录:
- 打开相关子目录 (
opendir()
)- 依次读取每个文件名 (
readdir()
) - 在相关文件的路径上使用
dlopen()
。 - 做任何与你相关的分析。
- 采用
dlclose()
- 依次读取每个文件名 (
- 采用
closedir()
- 打开相关子目录 (
另请参阅下面评论中的注释......完整的主题适度地充满了平台之间的差异。
我不确定是否有可能做到这一点并且是便携的。由于这个问题是关于 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)
.