[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