繁体   English   中英

在运行时更改 ctypes 的 LD_LIBRARY_PATH

[英]Changing LD_LIBRARY_PATH at runtime for ctypes

你如何在运行时更新这个环境变量,以便 ctypes 可以在任何地方加载库? 我尝试了以下方法,但似乎都不起作用。

from ctypes import *
os.environ['LD_LIBRARY_PATH'] = "/home/starlon/Projects/pyCFA635/lib"  
os.putenv('LD_LIBRARY_PATH', "/home/starlon/Projects/pyCFA635/lib")  
lib = CDLL("libevaluator.so")

当 Python 等程序运行时,动态加载器(ld.so.1 或类似的东西)已经读取了 LD_LIBRARY_PATH 并且此后不会注意到任何更改。 因此,除非 Python 软件本身评估 LD_LIBRARY_PATH 并使用它来构建dlopen()或要使用的等效函数的库的可能路径名,否则在脚本中设置变量将不起作用。

鉴于您说它不起作用,假设 Python 不会构建并尝试所有可能的库名称似乎是合理的; 它可能仅依赖于 LD_LIBRARY_PATH。

即使您提供 CDLL 或 cdll.LoadLibrary() 的完全限定路径,您可能仍需要在调用 Python 之前设置 LD_LIBRARY_PATH。 如果您加载的共享库显式引用了另一个共享库,并且没有在 .so 中为该库设置“rpath”,那么即使它已经被加载,也不会被找到。 库中的 rpath 指定用于搜索该库所需的其他库的搜索路径

比如我有一个案例,一组不是我自己制作的相互依赖的第三方库。 b.so 引用 a.so。 即使我提前加载 a.so:

ctypes.cdll.LoadLibrary('/abs/path/to/a.so')
ctypes.cdll.LoadLibrary('/abs/path/to/b.so')

我在第二次加载时遇到错误,因为 b.so 仅指代“a.so”,没有 rpath,因此 b.so 不知道那是正确的 a.so。 所以我必须提前设置 LD_LIBRARY_PATH 以包含'/abs/path/to'。

为了避免设置 LD_LIBRARY_PATH,您可以修改 .so 文件中的 rpath 条目。 在 Linux 上,我发现有两个实用程序可以执行此操作: chrpath 和patchelf chrpath 可从 Ubuntu 存储库中获得。 它无法更改 .so 上从未有过的 rpath。 patchelf 更灵活。

CDLL 可以传递一个完全限定的路径名​​,因此例如我在我的脚本之一中使用以下内容,其中 .so 与 python 脚本位于同一目录中。

import os
path = os.path.dirname(os.path.realpath(__file__))
dll = CDLL("%s/iface.so"%path)

在您的情况下,以下内容就足够了。

from ctypes import *
lib = CDLL("/home/starlon/Projects/pyCFA635/lib/libevaluator.so")

使用相对于当前工作目录的 rpath 编译二进制文件,例如:

gcc -shared -o yourbinary.so yoursource.c otherbinary.so \
    -Wl,-rpath='.',-rpath='./another/relative/rpath' -fpic

然后,您可以在运行时更改 python 中的工作目录:

import os
os.chdir('/path/to/your/binaries')

像这样,加载器也找到了其他动态库,比如otherbinary.so

将 LD_LIBRARY_PATH 设置为放置库的路径在此处不起作用,并且 ctypes 不会注意到任何更改。 因此,您需要在源代码中设置它并在脚本之前运行 ldconfig 以将其考虑在内。 此外,在脚本中设置 os 环境或任何 PATH 变量将不起作用。

我遇到了类似的问题,花了大约一天的时间来解决这个问题。

mkdir -p /etc/ld.so.conf.d/
echo "/home/starlon/Projects/pyCFA635/lib" > /etc/ld.so.conf.d/mycustomPath.conf

ldconfig

然后验证路径是否设置为:

ldconfig -v | less

完成后,尝试运行您的脚本。 这对我有用,也应该对你有用。

您可以在下面看到帮助我解决此问题的 URL:

https://www.cyberciti.biz/faq/linux-setting-changed-library-path/

注意:我意识到这个问题很旧,但是我想为此做出贡献,因为仅接受的答案实际上并不能解决我的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM