How to write partial of a buffer which was returned from a C function to a file?
Jach Fong
jfong at ms4.hinet.net
Fri Apr 13 21:57:53 EDT 2018
eryk sun at 2018/4/14 PM 05:27 wrote:
> On Fri, Apr 13, 2018 at 8:44 AM, Jach Fong <jfong at 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
More information about the Python-list
mailing list