[Pyrex] Casting python objects to void* and back
Robert Bradshaw
robertwb at math.washington.edu
Fri May 23 01:52:38 CEST 2008
I looks like your problems boil down to garbage collection, for
example, you wrote
> cdef void* pack_tuple( int i, int j ):
> t = ( i, j )
> return <void*>t
At the end of the function, t is deallocated... You need to manually
Py_INCREF(t) so it knows it needs to keep t around after the function
is done, and then figure out where (and when) to deallocate it.
- Robert
On May 22, 2008, at 4:16 PM, Venky Iyer wrote:
>
>> (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
>
>
> _______________________________________________
> Pyrex mailing list
> Pyrex at lists.copyleft.no
> http://lists.copyleft.no/mailman/listinfo/pyrex
More information about the Pyrex
mailing list