Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Allocating memory to pass back via ctypes callback function

83 views
Skip to first unread message

Scott

unread,
Jun 18, 2009, 7:19:27 PM6/18/09
to
Hi,

I'm using python ctypes to interact with the C API of a commercial-off-
the-shelf application. I need to implement callback functions which
will be called by the application. The callbacks take as a parameter
a char** parameter for which the callback function will allocate
memory and set the value of the underlying char*. The hitch is that I
need to allocate the memory with the vendor's own memory allocation
function because the caller will free the memory with the
corresponding vendor free function. The problem is that I can't quite
work out how to set the address of the incoming POINTER(c_char_p)
parameter to the location provided by the memory allocation function.

def my_callback(pointer_c_char_p):

py_string = get_string_to_pass_back()

address = VENDOR_malloc( len(py_string)*sizeof(c_char) )

# ???? how to set pointer_c_char_p.contents to memory location
address?

# ???? would this be the correct next thing to do?
pointer_c_char_p.contents = c_char_p(py_string)
# ????

return 0

Thanks,

Scott

Scott

unread,
Jun 19, 2009, 7:14:19 AM6/19/09
to
I think I found the answer to my own question. Can anyone spot any
issues with the following solution? The application I'm writing will
be hitting these callbacks pretty heavily so I'm nervous about mucking
up the memory management and creating one of those bugs that passes
undetected through testing but nails you in production.

def my_callback(p_cstring):
answer = 'foobar'

address = VENDOR_malloc(len(answer)+1)

cstring = c_char_p.from_address( address )

cstring.value = answer
p_cstring.contents = cstring
return

Nick Craig-Wood

unread,
Jun 22, 2009, 5:29:28 AM6/22/09
to
Scott <scott....@gmail.com> wrote:
> I think I found the answer to my own question. Can anyone spot any
> issues with the following solution? The application I'm writing will
> be hitting these callbacks pretty heavily so I'm nervous about mucking
> up the memory management and creating one of those bugs that passes
> undetected through testing but nails you in production.
>
> def my_callback(p_cstring):
> answer = 'foobar'
>
> address = VENDOR_malloc(len(answer)+1)
>
> cstring = c_char_p.from_address( address )

I think this allocates the pointer (the c_char_p) in the malloced
block, not the actual data...

> cstring.value = answer

And this overwrites the pointer

> p_cstring.contents = cstring
> return

If you try this, it gives all sorts of rubbish data / segfaults

memmove(address, address+1, 1)

Here is how I'd do it

from ctypes import *
from ctypes.util import find_library

c_lib = CDLL(find_library("c"))
malloc = c_lib.malloc
malloc.argtypes = [c_long]
malloc.restype = c_void_p

answer = 'foobar\0'

address = malloc(len(answer))
print address

cstring = c_char_p()
print addressof(cstring)

cstring.value = address
memmove(address, answer, len(answer))
print cstring.value
memmove(address, address+1, 1)
print cstring.value

Which prints

159611736
3084544552
foobar
ooobar


--
Nick Craig-Wood <ni...@craig-wood.com> -- http://www.craig-wood.com/nick

0 new messages