45

您如何在运行时更新此环境变量,以便 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")
4

5 回答 5

48

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

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

于 2009-05-13T05:57:52.107 回答
35

即使您提供了 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 更灵活。

于 2010-12-01T15:58:50.133 回答
18

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")
于 2009-08-04T08:20:48.670 回答
4

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

于 2016-02-08T14:19:27.273 回答
1

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

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

于 2020-05-12T06:47:46.993 回答