如何在运行时更新此环境变量,以便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")
Jonathan Lef.. 41
当Python等程序运行时,动态加载程序(ld.so.1或类似的东西)已经读取了LD_LIBRARY_PATH,并且此后不会发现任何更改.因此,除非Python软件本身评估LD_LIBRARY_PATH并使用它来构建库的可能路径名dlopen()
或要使用的等效函数,否则在脚本中设置变量将不起作用.
鉴于你说它不起作用,假设Python不构建并尝试所有可能的库名称似乎是合理的; 它可能仅依赖于LD_LIBRARY_PATH.
当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.参考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")