Wrapping C/C++ for Python using SWIG

PythonServer Side ProgrammingProgrammingC++C

There are multiple ways to wrap your existing C or C++ functionality in Python. In this section, we are going to see how we can wrap C/C++ functionality with SWIG. Below are other options to wrap c/c++ functionality in python.

  • Manual wrapping
  • Using pyrex to wrap C code.
  • Ctypes
  • SIP
  • Boost Python

SWIG (Simple Wrapper Interface Generator) is capable of wrapping C code with numerous other languages including Perl, Python, PHP, Ruby, Tcl, C#, Common Lisp (CLISP, Allegro, CL, UFFI, CFFI), Java, Modula-3 and OCAML. Swig also supports multiple interpreted and compiled Scheme implementations (like Guile, MzScheme, Chicken) are supported.

But we will discuss its implementation with python only here.

SWIG which is basically a macro language that comprehends C code and then will spit out wrapper code for the language of your choice.

Installation

I’m using the “swigwin-3.0.12” windows swig installer, you can download it from:

http://www.swig.org/download.html

Apart from that you may need “Microsoft Visual Studio 14.0” or higher to run swig program in windows.

To illustrate the use of swig, suppose we have some c function and we want to add it to other languages like Tcl, Perl, Python (I am interacting with python), Java and C#.

My c file is example.c

#include "example.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);
   }
}

Interface file:

Now, if you want to add you c file to your preferred language, you need to write an “interface file” which is the input to SWIG. My interface file for the example.c is,

example.i

/* File: example.i */
%module example
%{
   #define SWIG_FILE_WITH_INIT
   #include "example.h"
%}
%include "example.h"

Header file

We have included header file our previous example file. So here is my header file:

example.h

int fact(int n);

Setup file:

from distutils.core import setup, Extension
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"],
)

Creating the wrapper

Now we are going to create the python wrapper using our interface file (example.i). To create wrapper for your function, just run the below command on you CLI.

>swig -python example.i

Now if you see your current working directory, a new file is created just now. If you are using above filename as mine, then your wrapper file will be “example_wrap.c” else wrapper file will be named something like

“Your_File_Name” + “_wrapper” + “Your_language_extension”

So if your example file is test.c then your wrapper file will be “test_wrapper.c”.

Built the extension

>python setup.py build_ext
running build_ext
building '_example' extension
creating build
creating build\temp.win32-3.6
creating build\temp.win32-3.6\Release
….

That’s it now we are able to wrap our c language to python language. To check it you can run directly or create a virtual environment and run separately.

C:\Users\rajesh>mkdir swigExample && cd swigExample
C:\Users\rajesh\swigExample>virtualenv swigenv
Using base prefix 'c:\\python\\python361'
New python executable in C:\Users\rajesh\swigExample\swigenv\Scripts\python.exe
Installing setuptools, pip, wheel...done.

C:\Users\rajesh\swigExample>.\swigenv\Scripts\activate

(swigenv) C:\Users\rajesh\swigExample>python

That’s it, now from your file import function and run it.

>>> from example import fact
>>> fact(6)
720
raja
Published on 01-Apr-2019 12:04:01
Advertisements