如何在运行时更新此环境变量,这样的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。如果你明确地加载共享库指的是另一个共享库,并没有“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 /路径/到”。

要避免不必设置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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top