Python ctypes CDLL object destruction ordering upon sys exit

2024-10-02 10:22:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前面临一个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__中的断言经常失败(但并非总是失败),而其他断言从不失败。如果在Ctx.lib中保留对_lib的引用,也会出现这种情况。你知道吗

在本例中,通过友好地删除c(例如del cc = None或将其包装在with语句中),症状很容易修复。但总的来说,这些解决方案都不能令人满意,因为libz3.dll的用户不能总是在Python的GC启动之前很好地清理所有对象。你知道吗

有没有办法告诉Python不要将_lib设置为None,直到它真的不再需要了?你知道吗


Tags: 对象selfnoneoslibdefcontextctypes

热门问题