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 04:44:10 EDT 2018


eryk sun at 2018/4/13 PM 12:16 wrote:
> On Fri, Apr 13, 2018 at 12:38 AM, Jach Fong <jfong at ms4.hinet.net> wrote:
>> Gregory Ewing at 2018/4/13 上午 07:25 wrote:
>>
>>> To get around this, you may need to declare the return type
>>> as POINTER(c_char) instead:
>>>
>>>> For a general character pointer that may also point to binary data,
>>>
>>>   > POINTER(c_char) must be used.
>>
>> I had missed this statement:-(
>>
>> To make a quick try, I set the function's restype to
>> ctypes.POINTER(ctypes.c_ubyte), instead of ctypes.c_char_p. It's amazing,
>> the \x00 trap can be avoided in this way. Now I can use "mydata =
>> bytes(buf[:n])" to extract n bytes of data and write it to file.
> 
> Slicing a ctypes.POINTER(ctypes.c_char) pointer returns bytes without
> having to make a third copy via the bytes constructor. (Note that
> c_char is the fundamental C char integer type, not to be confused with
> c_char_p, which is a char * pointer.) However, if you're working with
> multi-megabyte data buffers,it's more efficient and safer to use an
> array view (ctypes or NumPy) on the returned buffer.

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:-)

from the ctypes document:
"Pointer instances are created by calling the pointer() function on a 
ctypes type"

"Fundamental data types, when returned as foreign function call results, 
or, for example, by retrieving structure field members or array items, 
are transparently converted to native Python types. In other words, if a 
foreign function has a restype of c_char_p, you will always receive a 
Python bytes object, not a c_char_p instance"

That's the reason I was failed at first using c_char_p as a pointer to 
the returned C buffer. There is no fundamental pointer type in ctypes. 
If a pointer was needed, you have to create it manually. That's why the 
second try works.

Anyway, thanks for help on cleaning my head:-)

--Jach

> 
> In most cases, you should free the returned pointer after you're
> finished processing the data buffer, else you'll have a memory leak.
> The library should export a function for this.
> 

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus



More information about the Python-list mailing list