C and Python

Start in JupyterHub

Python is a very high-level language and rather slow. But it is still possible to write your own fast code and execute it with Python as an interface. We will take a look at ctypes and CFFI as two ways to include your fast C-function into your python program.

# Create shared lib
!gcc -fPIC -shared pi.c -o libpiapprox.so

ctypes

from ctypes import *

libc = CDLL("libc.so.6") # cdll.msvcrt on Windows
print(libc.time(None))
printf = libc.printf
printf(b"%d bottles of beer\n", 42)

piapprox = CDLL("./libpiapprox.so")
pi_approx = piapprox.pi_approx
pi_approx.restype = c_float
print(pi_approx(5000))
1629705815
3.135999917984009

CFFI

from cffi import FFI
ffibuilder = FFI()

ffibuilder.cdef("float pi_approx(int n);")

ffibuilder.set_source("_pi",  # name of the output C extension
"""
    #include "pi.h"
""",
    sources=['pi.c'],   # includes pi.c as additional sources
    libraries=['m'])    # on Unix, link with the math library

if __name__ == "__main__":
    ffibuilder.compile(verbose=True)
generating ./_pi.c
the current directory is '/builds/fsvmatheinformatik/advancedpython/friday'
running build_ext
building '_pi' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/local/include/python3.9 -c _pi.c -o ./_pi.o
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/local/include/python3.9 -c pi.c -o ./pi.o
gcc -pthread -shared ./_pi.o ./pi.o -L/usr/local/lib -lm -o ./_pi.cpython-39-x86_64-linux-gnu.so
from _pi.lib import pi_approx

approx = pi_approx(10)
print(approx)

approx = pi_approx(10000)
print(approx)
3.5999999046325684
3.1803998947143555