Gregory Ewing at 2018/4/13 上午 07:25 wrote:
On Thu, Apr 12, 2018 at 2:16 PM, <jf...@ms4.hinet.net> wrote:
This C function returns a buffer which I declared it as a
ctypes.c_char_p. The buffer has size 0x10000 bytes long and the valid
data may vary from a few bytes to the whole size.
I think we need to see the code you're using to call this
The crucial issue is: are *you* allocating this 0x10000 byte
buffer and telling the function to read data into it, or
does the function allocate the memory itself and return a
pointer to it?
I am working on a DLL's function.
If the function is allocating the buffer, then I don't
think there's any way to make this work. The ctypes docs
Fundamental data types, when returned as foreign function call results
transparently converted to native Python types. In other words, if a
function has a restype of c_char_p, you will always receive a Python
object, not a c_char_p instance.
The problem is that the only way ctypes can tell how long
a bytes object to create for a c_char_p is by assuming that
it points to a nul-terminated string. If it actually points
to a char array that can legitimately contain zero bytes,
then you're out of luck.
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.
The problem was solved, and thanks for all your help.
I'm not sure where to go from here, though, because the
ctypes documentation peters out before explaining exactly
what can be done with a POINTER object.
Another approach would be to allocate the buffer yourself
and pass it into the C function, but whether that's possible
depends on the details of the C API you're using.
This email has been checked for viruses by Avast antivirus software.