我目前面临的问题是CDLL对象在仍需要时会消失。下面的代码将我的DLL加载到全局_lib
(对于好奇的,它是libz3.dll),声明一些DLL函数,然后创建一个Ctx对象,在其构造函数中调用CDLL,析构函数。
import sys, os, ctypes
class NC(ctypes.c_void_p):
def __init__(self, c): self._as_parameter_ = c
_lib = ctypes.CDLL(os.path.join(os.path.realpath('.'), 'libz3.dll'))
_lib.Z3_mk_context_rc.restype = NC
_lib.Z3_mk_context_rc.argtypes = [ctypes.c_void_p]
_lib.Z3_del_context.argtypes = [NC]
class Ctx:
def __init__(self):
global _lib
# self.lib = _lib
self.nctx = _lib.Z3_mk_context_rc(0)
assert _lib is not None, "in Ctx.__init__"
def __del__(self):
global _lib
assert _lib is not None, "in Ctx.__del__" # fails frequently
_lib.Z3_del_context(self.nctx)
# self.lib = None
c = Ctx()
assert _lib is not None, "global"
sys.exit(1)
我遇到的症状是Ctx.__del__
中的断言经常(但不总是)失败,而其他断言永远不会失败。如果我在_lib
中保留对Ctx.lib
的引用,也会出现这种情况。
在此示例中,症状很容易修复,好的并删除c
(例如del c
,c = None
或将其包装在with
语句中。但总的来说,这些解决方案都不令人满意,因为在Python的GC启动之前,不能期望libz3.dll的用户总是很好地清理所有对象。
有没有办法告诉Python不要将_lib
设置为None
,直到它真的不再需要为止?