使用dlopen在Python中加载.so文件时提示找不到同目录下的另一个.so文件
解决加载SO文件时依赖库找不到的问题
嘿,我碰到过一模一样的问题!你遇到的情况是动态链接器找不到libLMR_Demodulator.so——哪怕它和你要加载的libDemodulatorJNI_LMR.so在同一个目录,系统默认的动态库搜索路径里并不包含当前工作目录(或者你的Python进程实际运行的目录不是SO文件所在的目录)。下面给你几个可行的解决方案:
1. 确认并切换到SO文件所在目录
首先先检查你的Python脚本运行时的当前工作目录是不是SO文件所在的位置,加几行代码验证:
import os print("当前工作目录:", os.getcwd())
如果输出的路径不是SO文件的目录,先切换过去:
os.chdir("/绝对路径/到/你的SO文件目录")
然后再执行加载库的代码。
2. 设置LD_LIBRARY_PATH环境变量
动态链接器会从LD_LIBRARY_PATH指定的路径里搜索依赖库,你可以通过两种方式设置:
方式一:运行脚本前在终端设置
export LD_LIBRARY_PATH=/你的SO文件目录:$LD_LIBRARY_PATH python your_script.py
方式二:在Python脚本开头设置(要在导入ctypes之前)
import os # 把SO所在目录添加到LD_LIBRARY_PATH os.environ['LD_LIBRARY_PATH'] = '/你的SO文件目录:' + os.environ.get('LD_LIBRARY_PATH', '') # 之后再导入ctypes并加载库 import ctypes sh_obj = ctypes.cdll.LoadLibrary('./libDemodulatorJNI_LMR.so')
3. 先加载依赖库再加载目标库
利用ctypes.CDLL的加载标志,先把依赖的libLMR_Demodulator.so加载到全局符号表,这样后续加载目标库时就能找到它:
import ctypes # 先加载依赖库,指定RTLD_GLOBAL让符号全局可见 lib_dep = ctypes.CDLL('./libLMR_Demodulator.so', ctypes.RTLD_GLOBAL) # 再加载目标库 sh_obj = ctypes.CDLL('./libDemodulatorJNI_LMR.so', ctypes.RTLD_NOW) # 后续调用函数的代码不变 actual_start_frequency = sh_obj.getActualStartFrequency(ctypes.c_long(0)) print('The Current Actual Frequency Is: ' + str(actual_start_frequency))
4. 修改SO文件的rpath(长期解决方案)
如果这个SO文件是你自己编译的,或者你有权限修改它,可以用patchelf工具给它设置rpath,让它默认搜索自身所在的目录:
# 安装patchelf(如果没装的话) sudo apt install patchelf # 设置rpath为当前目录($ORIGIN表示SO文件所在路径) patchelf --set-rpath '$ORIGIN' libDemodulatorJNI_LMR.so
这样以后不管你把这个SO文件放到哪里,只要依赖库和它在同一目录,就能正常加载了。
内容的提问来源于stack exchange,提问作者Agustn Ernesto Cardeilhac Bans
相关产品推荐
相关产品推荐

