Re: [Python-Dev] ctypes: is it intentional that id() is the only way to get the address of an object?

2019年1月17日 05:53:53 -0800

On 1/17/19, Steven D'Aprano <[email protected]> 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
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to