[Pyrex] Casting python objects to void* and back
Venky Iyer
viyer at facebook.com
Fri May 23 01:16:22 CEST 2008
> (cross-posted to pyrex/cython, apologies if this is bad behavior)
>
> I've run into a number of issues with casting python objects to void* and
> back.
>
> Ultimately the reason I want to do this is to allow C functions to call python
> functions as callbacks, passing python callables as void* to C is a pattern
> that has been discussed on these lists multiple times.
>
> However, in addition to python callables, I want to figure out how I can pass
> other python objects to the python callback through the void* trick.
>
> Here is some test code for this:
>
> ---------
> void.pyx
> ---------
>
> cdef void* pack_tuple( int i, int j ):
> t = ( i, j )
> return <void*>t
>
> cdef void* pack_dict( int i, int j ):
> d = { 'i': i, 'j': j }
> return <void*>d
>
> cdef unpack_tuple( void* t ):
> u = <object>t
>
> print u
> print u[0]
> print u[1]
>
> # (<refcnt 0 at 0xb7d3ca2c>, 10)
> # (<refcnt 0 at 0xb7d3ca0c>, <type 'str'>)
> # 10
>
>
> cdef unpack_dict( void* d ):
> u = <object>d
>
> # print u
>
> # {'Py_Repr': [{...}, [...]]}
> # Fatal Python error: GC object already tracked
> # Aborted
>
> print u['i']
> print u['j']
>
> # 5
> # 10
>
> cpdef run_tuple(int i, int j):
> print "__Tuple__"
> cdef void* packed
> packed = pack_tuple(i,j)
> unpack_tuple(packed)
> print "Done"
>
> cpdef run_dict(int i, int j):
> print "__Dict__"
> cdef void* packed
> packed = pack_dict(i,j)
> unpack_dict(packed)
> print "Done"
>
> ------------
> void_test.py
> ------------
>
> import void
>
> if __name__ == "__main__":
>
> void.run_tuple(5,10)
> void.run_dict(5,10)
>
>
> --x-x-x---
>
> Here are the problems I'm encountering:
>
> 1) packing as a tuple just doesn't work. The first argument (5) cannot be
> retrieved. See output in comments above.
>
> 2) If I put in a dummy first argument in pack_tuple, like ('', 5, 10), I get
> (<nil>, 5, 10), but accessing index 0 segfaults. I can access index 1 and 2
> (containing 5 and 10 respectively) just fine though. What is going on here?
>
> 3) Packing as a dict seems to work well, except that if I try to print this
> dict, it aborts.
>
> 4) Calling run_tuple causes the program to hang on exit.
>
> 5) Lists behave similar to tuples.
>
> Any help would be greatly appreciated.
> For reference, I'm using
>
> $ cython -v
> Cython version 0.9.6.14
>
> $ uname -a
> Linux greyice 2.6.24-17-generic #1 SMP Thu May 1 14:31:33 UTC 2008 i686
> GNU/Linux
>
> $ gcc -v
> Using built-in specs.
> Target: i486-linux-gnu
> Configured with: ../src/configure -v
> --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr
> --enable-shared --with-system-zlib --libexecdir=/usr/lib
> --without-included-gettext --enable-threads=posix --enable-nls
> --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2
> --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr
> --enable-targets=all --enable-checking=release --build=i486-linux-gnu
> --host=i486-linux-gnu --target=i486-linux-gnu
> Thread model: posix
> gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu7)
>
> $ python -V
> Python 2.5.2
>
> Compilation and running:
>
> $ cython void.pyx
> $ gcc -c -fPIC -I/usr/include/python2.5/ void.c
> $ gcc -shared void.o -o void.so
> $ python void_test.py
>
> Thanks
> Venky Iyer
More information about the Pyrex
mailing list