sorin
sorin

Reputation: 170480

How do I save a binary buffer allocated via ctype malloc to a file in Python?

I have the following code

import ctypes
pBuf = ctypes.cdll.msvcrt.malloc(nBufSize)
# wrote something into the buffer

How do I save the content of the buffer to a file using Python 2.5?

As you may already know, this is not going to work, giving TypeError: argument 1 must be string or read-only buffer, not int:

f = open("out.data","wb"
f.write(pBuf)

Upvotes: 1

Views: 2264

Answers (2)

glglgl
glglgl

Reputation: 91049

Maybe it would better to have the buffer allocated with ctypes.create_string_buffer() instead of malloc(). In this case, you have access to the data via buf.raw.

If you need access to malloc()ed data, you can do so with ctypes.string_at(address, size), mybe combined with a cast to ctypes.c_void_p or ctypes.c_char_p, depending on what else you do with the memory and what is contained (\0 terminated string or data with known length).

Upvotes: 4

Adam Rosenfield
Adam Rosenfield

Reputation: 400284

Cast the buffer into a pointer to a byte array, and then get the value from that. Also, if you're on a 64-bit system, you'll need to make sure to set the return type of malloc to a c_void_p (not the default int) so that the return value doesn't lose any bits.

You'll also need to be careful, in case there are embedded NULs in your data -- you can't just convert the pointer into a c_char_p and convert that into a string (which is especially true if your data isn't NUL-terminated at all).

malloc = ctypes.dll.msvcrt.malloc
malloc.restype = ctypes.c_void_p

pBuf = malloc(nBufSize)
...
# Convert void pointer to byte array pointer, then convert that to a string. 
# This works even if there are embedded NULs in the string.
data = ctypes.cast(pBuf, ctypes.POINTER(ctypes.c_ubyte * nBufSize))
byteData = ''.join(map(chr, data.contents))

with open(filename, mode='wb') as f:
    f.write(byteData)

Upvotes: 3

Related Questions