eryk sun at 2018/4/14 PM 05:27 wrote:
On Fri, Apr 13, 2018 at 8:44 AM, Jach Fong <jf...@ms4.hinet.net> wrote:
After studying the example you explained in your previous post replied to
Gregory Ewing, I had noticed that until today I was totally misunderstand
the meaning of the c_char_p. I always think it "is" a pointer, but actually
it's just a ctypes type, maybe literarily looks like a C pointer, but not a
pointer from the ctypes view at all:-)
Here's a list of type classes in ctypes:
class metaclass
=================================
_SimpleCData PyCSimpleType
_Pointer PyCPointerType
_CFuncPtr PyCFuncPtrType
Array PyCArrayType
Structure PyCStructType
Union UnionType
These classes share a common _CData base class. Note that the _ctypes
extension module doesn't directly expose _CData, nor any of the
metaclasses.
ctypes type checking primarily uses Python type checking, so we
generally do not subclass these types directly, except for Structure
and Union. Instead we have a set of predefined simple types that
subclass _SimpleCData (e.g. c_int, c_char), and we use factory
functions to create pointer types (e.g. POINTER, CFUNCTYPE), which
cache the created type. For arrays, we rely on the base _CData
sequence-repeat functionality (e.g. c_int * 3), which also caches the
Array subclass that it creates.
Type caching ensures that two expressions that create an equivalent C
type return the same class. For example, if you have `c_char * 3` in
two places, it should be the same type:
>>> cls = ctypes.c_char * 3
>>> (ctypes.c_char * 3) is cls
True
Thanks for your description. To digest it, I may need to dive into its
source jungle:-(
The simple types c_void_p, c_char_p, and c_wchar_p are pointers.
However, since they subclass _SimpleCData instead of _Pointer, they
inherit the behavior of simple types.
The ctypes document says:
"Pointer instances have a contents attribute which returns the object to
which the pointer points"
>>> buf0 = ctypes.create_string_buffer(b'spam')
>>> pvoid = ctypes.c_void_p(ctypes.addressof(buf0))
>>> pvoid.contents
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'c_void_p' object has no attribute 'contents'
>>> pvoid.value
35425816
>>> pp = ctypes.pointer(buf0)
>>> pp.contents
<ctypes.c_char_Array_5 object at 0x021C8F30>
>>> pp.value
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'LP_c_char_Array_5' object has no attribute 'value'
It looks like the c_void_p is not of a pointer type:-)
--Jach
In particular they have get/set
functions that implicitly convert to and from native Python types when
they're used in aggregate types (arrays, structs, unions), when
indexing or slicing a _Pointer instance, or as the result or argument
of a function pointer (i.e. _CFuncPtr subclass).
---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
--
https://mail.python.org/mailman/listinfo/python-list