On 1/17/19, Steven D'Aprano <st...@pearwood.info> wrote: > > I understand that the only way to pass the address of an object to > ctypes is to use that id. Is that intentional?
It's kind of dangerous to pass an object to C without an increment of its reference count. The proper way is to use a simple pointer of type "O" (object), which is already created for you as the "py_object" type. >>> ctypes.py_object._type_ 'O' >>> ctypes.py_object.__bases__ (<class '_ctypes._SimpleCData'>,) It keeps a reference in the readonly _objects attribute. For example: >>> b = bytearray(b'spam') >>> sys.getrefcount(b) 2 >>> cb = ctypes.py_object(b) >>> sys.getrefcount(b) 3 >>> cb._objects bytearray(b'spam') >>> del cb >>> sys.getrefcount(b) 2 If you need the address without relying on id(), cast to a void pointer: >>> ctypes.POINTER(ctypes.c_void_p)(cb)[0] == id(b) True Or instantiate a c_void_p from the py_object as a buffer: >>> ctypes.c_void_p.from_buffer(cb).value == id(b) True Note that ctypes.cast() doesn't work in this case. It's implemented as an FFI function that takes the object address as a void pointer. The from_param method of c_void_p doesn't support py_object: >>> ctypes.c_void_p.from_param(cb) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: wrong type _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com