I wrote some code months ago to output 1-bit-per-pixel PNG files from Python, doing direct calls to libpng using ctypes, because PIL didn't give me sufficient control over colour tables and pixel depths.
I thought the code was working fine. I left it aside for some months, came back to it a week or two ago, and found it was crashing. I was creating CFUNCTYPE objects to do callbacks to my own I/O routines, and with GDB I was able to narrow down the crashes to the point where libpng was trying to invoke one of my callbacks. What had changed? I had switched my OS from Gentoo to Debian Unstable. I chrooted back to the Gentoo system, tried my script again--still crashed. Went back to the doc <http://docs.python.org/library/ctypes.html> and tried the qsort callback example. Worked fine! And then I noticed this little bit: Important note for callback functions: Make sure you keep references to CFUNCTYPE objects as long as they are used from C code. ctypes doesn’t, and if you don’t, they may be garbage collected, crashing your program when a callback is made. Yup, that was it. I changed my installation of the callbacks from png.png_set_write_fn \ ( write_struct, None, ct.CFUNCTYPE(None, ct.c_void_p, ct.c_void_p, ct.c_size_t)(write_data), ct.CFUNCTYPE(None, ct.c_void_p)(flush_write) ) to cb_write_data = ct.CFUNCTYPE(None, ct.c_void_p, ct.c_void_p, ct.c_size_t)(write_data) cb_flush_write = ct.CFUNCTYPE(None, ct.c_void_p)(flush_write) png.png_set_write_fn \ ( write_struct, None, cb_write_data, cb_flush_write ) and it works again. -- http://mail.python.org/mailman/listinfo/python-list
