eryk sun at 2018/4/13 PM 12:16 wrote:
On Fri, Apr 13, 2018 at 12:38 AM, Jach Fong <jf...@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

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to