C Extension with Python
Goal
Python allows you to call a library developed in C/C++.
Requisite
GCC compiler to compile C code
Swig to compile C into C wrapper for python
Create a project directory.
$ mkdir project && cd project
Create a c header file - example.h (just one line)
int fact(int n);
Create a definition file - example.c
#include "example.h"
#include "stdio.h"
int fact(int n) {
if (n < 0){ /* This should probably return an error, but this is simpler */
return 0;
}
if (n == 0) {
return 1;
}
else {
/* testing for overflow would be a good idea here */
return n * fact(n-1);
}
}
int main(void){
int v = fact(10);
printf("Result: %d", v);
}
Create an interface file for Swig
%module example
%{
#define SWIG_FILE_WITH_INIT
#include "example.h"
%}
int fact(int n);
Lastly create a python distutils setup file - setup.py
#!/usr/bin/env python
"""
setup.py file for SWIG example
"""
from distutils.core import setup, Extension
# Underscore in the extension name is requirement of Swig.
example_module = Extension('_example', sources=['example_wrap.c', 'example.c'])
setup (name = 'example',
version = '0.1',
author = "SWIG Docs",
description = """Simple swig example from docs""",
ext_modules = [example_module],
py_modules = ["example"])
Check swig version
$ swig -version
SWIG Version 3.0.12
Compiled with clang++ [x86_64-apple-darwin18.0.0]
...
Check gcc version
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin18.2.0
...
Check python version
$ python --version
Python 3.6.6 :: Anaconda custom (64-bit)
Run swig utility to create the wrapper c files.
$ swig -python example.i
Run python dist setup tool to build the module
$ python setup.py build_ext --inplace
Call factorial function from python
$ python -c "import example; print(example.fact(10))"
3628800