Cython to Wrap Existing C Code
What is Cython ?
It is an optimizing static compiler for both the Python programming language and the extended Cython programming language. It is used to make it easy to write C extensions for Python as easy as Python itself.
It comes up with many helpful features :
- Writing a Python code that calls back and forth from and to C/C++ code.
- Easily tuning of readable Python code into plain C performance by adding static type declarations.
- Use of combined source code level debugging to find bugs in given Python, Cython and C code.
- Efficient interaction with large data sets, e.g. using multi-dimensional NumPy arrays.
- Integration with existing code and data from low-level or high-performance libraries and applications.
To make an extension with Cython is a tricky task to perform. Doing so, one needs to create a collection of wrapper functions. Assuming that the work code shown has been compiled into a C library called libwork. The code below will create a file named
Code #1 :
In Cython, the code above will work as a C header file. The initial declaration cdef extern from
"work.h" declares the required C header file. Declarations that follow are taken from the header. The name of this file is
cwork.pxd. Next target is to create a
work.pyx file which will define wrappers that bridge the Python interpreter to the underlying C code declared in the
Code #2 :
Code #3 :
Finally, to build the extension module, create a
Code #5 : Building resulting module for experimentation.
Now, we have an extension module
work.so. Let’s see how it works.
Code #6 :
GCD : 4 Division : (4, 2) Average : 2.0 pt1 : <capsule object "Point" at 0x1005d1e70> pt2 : <capsule object "Point" at 0x1005d1ea0> Distance between the two points : 2.8284271247461903
At a high level, using Cython is modeled after C. The .pxd files merely contain C definitions (similar to
.h files) and the
.pyx files contain implementation (similar to a
.c file). The cimport statement is used by Cython to import definitions from a
.pxd file. This is different than using a normal Python import statement, which would load a regular Python module.