User guide

NumPy User Guide, Release 1.9.0
are getting and how to interface them with C-like constructs.
2. Inappropriate Pyrex syntax or incorrect calls to C-code or type- mismatches can result in failures such as
(a) Pyrex failing to generate the extension module source code,
(b) Compiler failure while generating the extension module binary due to incorrect C syntax,
(c) Python failure when trying to use the module.
3. It is easy to lose a clean separation between Python and C which makes re-using your C-code for other non-
Python-related projects more difficult.
4. Multi-dimensional arrays are “bulky” to index (appropriate macros may be able to fix this).
5. The C-code generated by Pyrex is hard to read and modify (and typically compiles with annoying but harmless
warnings).
Writing a good Pyrex extension module still takes a bit of effort because not only does it require (a little) familiarity
with C, but also with Pyrex’s brand of Python-mixed-with C. One big advantage of Pyrex-generated extension modules
is that they are easy to distribute using distutils. In summary, Pyrex is a very capable tool for either gluing C-code or
generating an extension module quickly and should not be over-looked. It is especially useful for people that can’t or
won’t write C-code or Fortran code. But, if you are already able to write simple subroutines in C or Fortran, then I
would use one of the other approaches such as f2py (for Fortran), ctypes (for C shared- libraries), or weave (for inline
C-code).
5.2.6 ctypes
Ctypes is a python extension module (downloaded separately for Python <2.5 and included with Python 2.5) that
allows you to call an arbitrary function in a shared library directly from Python. This approach allows you to interface
with C-code directly from Python. This opens up an enormous number of libraries for use from Python. The drawback,
however, is that coding mistakes can lead to ugly program crashes very easily (just as can happen in C) because there is
little type or bounds checking done on the parameters. This is especially true when array data is passed in as a pointer
to a raw memory location. The responsibility is then on you that the subroutine will not access memory outside the
actual array area. But, if you don’t mind living a little dangerously ctypes can be an effective tool for quickly taking
advantage of a large shared library (or writing extended functionality in your own shared library).
Because the ctypes approach exposes a raw interface to the compiled code it is not always tolerant of user mistakes.
Robust use of the ctypes module typically involves an additional layer of Python code in order to check the data types
and array bounds of objects passed to the underlying subroutine. This additional layer of checking (not to mention
the conversion from ctypes objects to C-data-types that ctypes itself performs), will make the interface slower than a
hand-written extension-module interface. However, this overhead should be neglible if the C-routine being called is
doing any significant amount of work. If you are a great Python programmer with weak C-skills, ctypes is an easy
way to write a useful interface to a (shared) library of compiled code.
To use c-types you must
1. Have a shared library.
2. Load the shared library.
3. Convert the python objects to ctypes-understood arguments.
4. Call the function from the library with the ctypes arguments.
Having a shared library
There are several requirements for a shared library that can be used with c-types that are platform specific. This guide
assumes you have some familiarity with making a shared library on your system (or simply have a shared library
72 Chapter 5. Using Numpy C-API