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