Calling C code from Python via Cython

If you need more information what Cython is, take a look here: http://cython.readthedocs.io/.

This sample, is a simple “Hello world” code for macOS based installation of Python and Cython.

First step is to get Cython for your platform. You can use pip to achieve that

# Installation of Cython at macOS
# I prefer to use Virtualenv contrary to OS based installation
# If you need more info about Virtualenv, take a look here
#
# https://virtualenv.pypa.io/

> virtualenv venv
> source venv/bin/activate
> pip install Cython

After you are done with that, you can create sample code. We will call method in C that accepts one argument – char * – and prints the string on stdout.

/* hello.c */
#include <stdio.h>

void f(char *str) {
      printf("str: %s\n", str);
}

Next thing we need is a Cython based wrapper for the code we want to call

''' hello_caller.pyx '''

cdef extern from "hello.c":
  void f(char *)

'''
    take a look here for details about different Cython declarations

    http://notes-on-cython.readthedocs.io/en/latest/function_declarations.html
'''
cpdef hello_world(str):
  f(str)

Last thing we need is a setup.py script for Cython that will perform the build

''' setup.py '''
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

sourcefiles = ['hello_caller.pyx']
ext_modules = [Extension("hello_caller",
                          sourcefiles )]

setup(
  name = 'Hello world',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules
)

After everything is set up, we can build everything

> python setup.py build_ext --inplace

and, eventually, we can call C code from Python code

''' script.py '''
#!/bin/python

import hello_caller

message = "Hello world"
hello_caller.hello_world(message)

by running

> python ./script.py
str: Hello world