[Pyrex] Casting Python sequence to pointer and vice versa
Christian Heimes
lists at cheimes.de
Fri Mar 2 12:05:46 UTC 2007
Hello!
I'm new to Pyrex. I had a lot of trouble casting a python sequence to a
pointer and the other way around. It required a lot of boiler plate code
and I hit a nasty gotcha.
ctypedef unsigned long ULong
cdef extern from "stdlib.h":
ctypedef unsigned long size_t
void *malloc(size_t size)
void free(void* ptr)
size_t sizeof(void *)
def xtea_encryptQuad(object block, key, UInt rounds):
cdef *v
cdef int size, vsize, i
size = len(block)
vsize = sizeof(ULong) * size
v = <ULong *>malloc(vsize)
for i from 0 <= i < size:
v[i] = block[i]
[more code]
result = []
for i from 0 <= i < size:
result.append(v[i])
free(v)
problem 1: The cdef extern from "stdlib.h" block isn't intuitive.
Although I know that the C functions are declared in stdlib.h I had to
google for the correct declarations.
problem 2 (the nasty gotcha): The usual malloc(sizeof(ULong)*size)
statement failed with a cryptic error message. It took me a while before
I found some pyrex code in another project with sizeof() and malloc().
It works when the statement is separated into two statements.
I wish Pyrex could get some nice PyArg_Parse() like methods to make our
lives either. Example code:
cdef ULong *v
cdef int size, rc
block = (1, 2, 3)
# cast Python block of unsigned longs (k) to unsigned long pointer
# return size or -1 in the case of an error
size = Py2Ptr(block, 'k', v)
if size < 0:
raise ValueError
[...]
result = []
rc = Ptr2Py(v, size, 'k', result)
if rc < 0:
raise ValueError
free(v)
Christian
More information about the Pyrex
mailing list