Python中cdll加载动态库后如何指定资源加载的工作目录?
动态库依赖资源的路径问题解决方法
问题背景
你的文件结构如下:
dir_a/script.py dir_a/lib/lib.so dir_a/model/model.bin
通过ctypes加载动态库的代码能正确解析库的路径,即使在非脚本所在目录运行也没问题,但动态库内部通过硬编码的model/model.bin相对路径加载资源时,只有在dir_a目录下运行脚本才能正常访问。
可行解决方案
1. 加载库前切换进程工作目录
动态库使用的相对路径是基于当前进程的工作目录解析的,所以在加载库之前,把进程工作目录切换到dir_a即可:
from ctypes import * from os import path, chdir script_dir = path.dirname(path.realpath(__file__)) # 切换到脚本所在的dir_a目录 chdir(script_dir) lib_path = path.join(script_dir, "lib/lib.so") lib = cdll.LoadLibrary(lib_path)
注意:如果脚本后续有依赖原工作目录的操作,需要在完成库的资源加载后切换回原目录。
2. 修改动态库,传入资源的完整路径
如果有权限修改动态库的源码,可以给库添加一个初始化接口,让Python脚本传递model.bin的完整路径:
- Python端代码:
from ctypes import * from os import path script_dir = path.dirname(path.realpath(__file__)) lib_path = path.join(script_dir, "lib/lib.so") lib = cdll.LoadLibrary(lib_path) # 构造model.bin的完整路径并传递给库 model_full_path = path.join(script_dir, "model/model.bin").encode('utf-8') # 假设库提供了set_model_path函数接收路径参数 lib.set_model_path(model_full_path)
- C库端修改:将硬编码的
model/model.bin替换为传入的路径参数。
3. 通过环境变量指定资源根目录
如果动态库支持读取环境变量来查找资源,可以在加载库前设置环境变量:
from ctypes import * from os import path, environ script_dir = path.dirname(path.realpath(__file__)) # 设置环境变量指向资源根目录dir_a environ['LIB_RESOURCE_ROOT'] = script_dir lib_path = path.join(script_dir, "lib/lib.so") lib = cdll.LoadLibrary(lib_path)
然后在C库中读取该环境变量,拼接出model.bin的完整路径。
内容的提问来源于stack exchange,提问作者Sergey Mozhaykin
相关产品推荐
相关产品推荐

