干净地卸载共享库并使用 Python CFFI 重新开始
Posted
技术标签:
【中文标题】干净地卸载共享库并使用 Python CFFI 重新开始【英文标题】:Cleanly unload shared library and start over with Python CFFI 【发布时间】:2015-06-16 12:18:48 【问题描述】:我正在像这样设置和打开一个 DLL:
from cffi import FFI
ffi = FFI()
api_path = '/path_to/api.h'
lib_path = '/path_to/lib.so'
with open(api_path) as f:
ffi.cdef(f.read())
mylib = ffi.dlopen(lib_path)
myfunc_c = ff.callback('int (char *)', myfunc)
#etc...
如何关闭库并再次打开它?如果我这样做了
del mylib
然后再次尝试上面的代码我得到CDefError: cannot parse ...
when
尝试ffi.cdef()
。
我看到了一些使用 dlclose()
的 ctypes 示例,但找不到 CFFI 的等价物。
谢谢。
【问题讨论】:
【参考方案1】:dlclose(lib)
存在,但仅适用于离线/预编译的 FFI。
http://cffi.readthedocs.io/en/latest/cdef.html#ffi-dlopen-loading-libraries-in-abi-mode
【讨论】:
【参考方案2】:抱歉,CFFI 无法显式调用 C 级 dlclose()
。只有当库对象超出范围时才会隐式调用它。此外,ffi
对象使该库保持活动状态,因此 ffi
也需要超出范围。
如果你真的想这样做,你需要确保所有对mylib
和ffi
的引用都消失了,然后调用gc.collect()
。 (如果你想重新加载,你需要用一个新的ffi = FFI()
重新开始。)
CFFI 的下一个版本可能会添加类似 ffi.close_libraries()
的内容,以卸载在此 ffi
对象中加载的库。
编辑:它不适用于在 CPython 上加载了 verify()
的库,因为这些是常规的 CPython C 扩展模块,而 CPython 永远不会卸载其 C 扩展模块。这意味着一般的ffi.close_libraries()
想法可能注定要失败......
【讨论】:
以上是关于干净地卸载共享库并使用 Python CFFI 重新开始的主要内容,如果未能解决你的问题,请参考以下文章