On May 20, 2013, at 8:54 PM, C Anthony Risinger <[email protected]> wrote:
> i know the impl is pretty simple, but i havent had the opportunity to > complete yet -- are there other reasons to use cffi over ctypes? my > experience with ctypes is not extensive either. The real reason to prefer it is that ctypes communicates with C code at the ABI level, whereas cffi uses the API level. When you read documentation for a C library, it generally goes like: you should include <foo.h> you should call a function that looks like 'int foo_bar(char* baz, qux_t qux)' you should link against -lfoo When you use cffi, this is all you need to know. You act on 'include <foo.h>' by putting it in your 'verify' section; you act on 'call a function that looks like' by pasting the 'looks like' into your 'cdef' section, and you link against -lfoo by passing arguments as if you were building a distutils extension with libfoo.so. So, you do each of these things in a previously-accepted, well-documented way. If you get any of these things wrong, you will most likely get a nice, comprehensible C compiler error message, that points at some very comprehensible generated C code. (Of course you can screw up regular C programming stuff and induce the library to dereference a freed pointer or something and get a segfault, but this is actually much harder with cffi than with actual C code, for most of the regular reasons that Python code is safer, and also some cffi-specific things about the way it handles pointers.) If you move this code to a system with different linker properties or header files, you get exactly the same behavior a C programmer would get, with compile errors that indicate you've got the wrong version of foo.h or link errors that tell you it can't find libfoo, during the build process. Whereas, with ctypes, you act on 'include <foo.h>' by reading foo.h with a magnifying glass, and maybe running 'cpp' over it and running the output. You act on 'call a function that looks like' by putting your debugger hat on and inspecting 'foo_bar' to figure out if that's really a function, or a macro that just *looks* like a function call that does some other funky thing, or a macro that simply re-names a versioned symbol; you need to find the actual symbol name in your local copy of the library. You need to figure out the precise memory layout of 'qux' so you can re-describe it. If you get any of these things wrong, you get a segfault, possibly at some random later point in your program. If you move to a system with different linker properties or header files, you'd better hope everything matches your development system exactly or you've written custom code to detect that platform, because the C compiler can't help you and there isn't enough metadata in the C library to tell you that your bindings are now wrong. To make matters worse, you can't really tell that anything's broken until your program is running; it will fail late, and in weird ways. Sorry for such a long message, but I recently had the experience of playing with cffi to wrap some C code and it was just _great_, whereas my previous experiences with ctypes were mediocre to miserable. If you're going to wrap some C code I really recommend giving it a try. If you're interested, more info is available here: <http://cffi.readthedocs.org/en/latest/> -glyph -- --- You received this message because you are subscribed to the Google Groups "Pyjs.org Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
