在运行时为ctypes更改LD_LIBRARY_PATH

问题描述 投票:37回答:5

如何在运行时更新此环境变量,以便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 ctypes
5个回答
41
投票

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

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


30
投票

即使您提供了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。可从Ubuntu存储库中获取chrpath。它无法更改从未有过的.so上的rpath。 patchelf更加灵活。


16
投票

可以给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")

3
投票

使用相对于当前工作目录的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


0
投票

将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-changing-library-path/

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

© www.soinside.com 2019 - 2024. All rights reserved.