干净地卸载共享库并使用 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 也需要超出范围。

如果你真的想这样做,你需要确保所有对mylibffi 的引用都消失了,然后调用gc.collect()。 (如果你想重新加载,你需要用一个新的ffi = FFI()重新开始。)

CFFI 的下一个版本可能会添加类似 ffi.close_libraries() 的内容,以卸载在此 ffi 对象中加载的库。

编辑:它不适用于在 CPython 上加载了 verify() 的库,因为这些是常规的 CPython C 扩展模块,而 CPython 永远不会卸载其 C 扩展模块。这意味着一般的ffi.close_libraries() 想法可能注定要失败......

【讨论】:

以上是关于干净地卸载共享库并使用 Python CFFI 重新开始的主要内容,如果未能解决你的问题,请参考以下文章

win10系统下把Oracle卸载干净

使用 ctypes/cffi 解决循环共享对象依赖关系

干净卸载Anaconda

怎么卸载已经安装的python

SQL卸载不干净,重装失败。

cad卸载不干净无法重装该怎么办?