如何使用 ctypes 从 Python 包装器 class 安全地调用 C++ class 的析构函数?

How to call destructor of C++ class safely from a Python wrapper class using ctypes?

我构建了一个 C++ 共享库,它导出用于构造、破坏和与已实现 class 交互的函数。我想在 Python 中编写一个包装器 class,它加载已编译的 .dll 并使用 ctypes 将所有函数包装为 class。

如何安全地包装 C++ class 的析构函数,以便在任何情况下(正常垃圾收集、异常等)调用它?

根据Python的data model doc

Objects are never explicitly destroyed; however, when they become unreachable they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether...

...

Some objects contain references to “external” resources such as open files or windows. It is understood that these resources are freed when the object is garbage-collected, but since garbage collection is not guaranteed to happen, such objects also provide an explicit way to release the external resource, usually a close() method. Programs are strongly recommended to explicitly close such objects. The try…finally statement and the with statement provide convenient ways to do this.

所以即使在大多数情况下__del__一个对象的方法正在被GC调用,也不能保证。 with 声明(来自 PEP 343) on the other hand guarantees that if __enter__ method of the object succeeded, then __exit__ method will be called at the end of the statement, both in case of normal execution and in case of exception. (More detailed in

一个示例可能如下所示,使用 PEP 343 示例中的“object-closing”上下文管理器,以及一个包装器 class 和 close 方法调用本机对象的析构函数:

class NativeObjectWrapper(object):
    def __init__(self):
        self.nativeObject = nativeLib.CreateInstance()
    def close(self):
        nativeLib.DestructorFunction(self.nativeObject)
        
class closing(object):
    def __init__(self, obj):
        self.obj = obj
    def __enter__(self):
        return self.obj
    def __exit__(self, *exc_info):
        try:
            close_it = self.obj.close
        except AttributeError:
            pass
        else:
            close_it()
            
#example of usage
with closing(NativeObjectWrapper()) as objectWrapper:
    ... #some usage of native wrapper