如何让Python-CFFI自动定位同目录下的libmylib.so共享库?
解决CFFI生成模块无法加载同目录共享库的问题
针对你遇到的问题,这里有几个无需修改系统配置的解决方案:
方案1:编译时嵌入rpath(推荐)
在编译CFFI模块时,通过链接器参数-Wl,-rpath,$ORIGIN让生成的共享库优先从自身所在目录加载依赖。这个方法最彻底,编译后模块无需额外处理即可正常导入。
修改你的lib_builder.py中set_source的参数,添加extra_link_args:
ffibuilder.set_source('_mylib_cffi', """ #include "mylib.h" static uint32_t handle = 0xffffffff; int start(int port) { mylib_init(0); mylib_register_publisher("127.0.0.1", port, &handle, 0); return 1; } int ready(void) { return handle != 0xffffffff; } int publish(char *buf, int len) { return mylib_publish(handle, buf, len); } int stop(void) { mylib_shutdown(); return 1; } """, libraries=['mylib'], library_dirs=[os.path.dirname(__file__)], extra_link_args=['-Wl,-rpath,$ORIGIN']) # 新增这一行
重新编译后,生成的_mylib_cffi模块会自动在自身目录查找libmylib.so。
方案2:导入前动态修改LD_LIBRARY_PATH
在Python代码导入模块前,临时将共享库所在目录添加到LD_LIBRARY_PATH环境变量中,这个修改仅对当前Python进程有效,不会影响系统全局配置:
import os import sys # 获取libmylib.so所在目录(假设和当前脚本同目录) lib_dir = os.path.dirname(os.path.abspath(__file__)) # 临时修改环境变量 os.environ['LD_LIBRARY_PATH'] = f"{lib_dir}:{os.environ.get('LD_LIBRARY_PATH', '')}" # 现在可以正常导入模块 import _mylib_cffi
方案3:用ctypes预加载共享库
先通过ctypes手动加载指定路径的libmylib.so,再导入CFFI生成的模块。因为系统会优先使用已加载的共享库,这样CFFI模块就不会再去查找其他路径:
import ctypes import os lib_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'libmylib.so') # 加载共享库 ctypes.CDLL(lib_path, mode=ctypes.RTLD_GLOBAL) # 导入CFFI模块 import _mylib_cffi
CFFI学习小建议
- 如果你的封装需求不复杂,也可以尝试使用CFFI的
dlopen模式,无需编译生成模块,直接在Python中加载并封装共享库:
这种方式更灵活,适合快速测试或简单封装场景。from cffi import FFI ffi = FFI() ffi.cdef(""" int start(int port); int ready(void); int publish(char *buf, int len); int stop(void); """) # 直接加载指定路径的共享库 mylib = ffi.dlopen(os.path.join(os.path.dirname(__file__), 'libmylib.so')) # 调用接口 mylib.start(8080)
内容的提问来源于stack exchange,提问作者ZioByte
相关产品推荐
相关产品推荐

