For everyone who managed to reply *hours* after Eryk Sun posted the correct answer and still get it wrong, here it is again in full.
As a bonus, here's a link to the place where this answer appears in the documentation: https://docs.python.org/3/library/ctypes.html#ctypes.py_object Cheers, Steve On 17Jan.2019 0550, eryk sun wrote: > 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