Wrapping C/C++ for Python using SWIG – Set 1
Last Updated :
07 Jul, 2017
There is no doubt that C is faster than Python then how do Python library like Numpy perform huge number crunching job so fast and efficiently? Actually, libraries like Numpy are not completely written in Python instead, some parts of the library are written in C which provides performance boost. After writing code in C, we wrap them in Python code which acts like an interface for those C codes. We can then call C functions using Python syntax where actual processing is done in C behind the scene and the result is returned back as Python object. In this article, we will see how to create Python wrapper for our C program on Linux systems using a software called SWIG.
What is SWIG
In a nutshell, SWIG is a compiler that takes C/C++ declarations and creates a wrapper needed to access those declarations from other languages like Python, Tcl, Ruby etc.
It normally required no changes in existing code and create an interface within a minute.
Reasons for creating wrapper
In many occasions we need wrappers, following are few of them –
- Building interpreted interface for existing C programs.
- Building high-performance C modules for scripting languages
- It’s huge pain to test huge C programs, so we write wrappers in some scripting languages like Python, where it’s very easy to write test. etc
Installing SWIG
For downloading SWIG directly from apt repository type following commands –
sudo apt-get update
sudo apt-get install swig
Writing Wrapper using SWIG
Consider this piece of C code, having two functions and one global variable –
#include <stdio.h>
#include <math.h>
#include "gfg.h"
#define ll long long
double myvar = 3.4;
ll int fact(ll int n)
{
if (n <= 1)
return 1;
else
return (n * fact(n-1));
}
int my_mod( int n, int m)
{
return (n % m);
}
|
Here is our header file gfg.h –
long long int fact( long long int n);
int my_mod( int n, int m);
|
First, we have to create a SWIG Interface file. This file contains ANSI C function prototypes and variable declaration. Here –
- The %module directive specifies the name of the module we will use in Python.
- %{ .. %} block provides a location to insert additional code such as C header files or additional C declaration into the generated wrapper code.
- %include directive let us include additional files like header files.
%module gfg
%{
#include "gfg.h"
double myvar;
%}
double myvar;
long long int fact( long long int n1);
int my_mod( int m, int n);
|
Now we will create wrapper code using the command like $ swig -target_language interface_file.i
$ swig -python gfg.i
After executing this command a wrapper code with name “gfg_wrap.c” is created. This files contains a bloated version of our original C code with various error handling code etc. Another file “gfg.py” is generated which is the module we will import in our python script.
After this, we have to generate position-independent code which will be used in shared library by compiling “gfg_wrap.c” and “gfg.c” using the following command –
$ gcc -c -fpic gfg_wrap.c gfg.c -I/use/include/python2.7
Replace python2.7 with your Python version. This will generate two object files
“gfg_wrap.o” and “gfg.o”. In above command –
- -fpic generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. Such code accesses all constant addresses through a global offset table (GOT)
Note: If you get error something like “… ‘Python.h’ file not found” then following might be possible causes –
- You might not have ‘Python.h’ file or
- You are providing wrong location of ‘Python.h’ file to compiler
To get ‘Python.h’ You must install Python-dev using following command –
$ sudo apt-get install python-dev
To find the correct path of ‘Python.h’ execute following command –
$ python-config --cflags
This will output something like this –

Now replace the path in compilation command with this one for python2.7 or change the version as python3.5 for Python 3.5.
Now, at last, we have to link generated objects files together to create a shared object which is analogous to dll files in windows. Use the following command, this will generate a “_gfg.so” shared object file –
$ gcc -shared gfg.o gfg_wrap.o -o _gfg.so
Now we are ready to test out python wrapper by importing it. Make sure you are in directory having this wrapper file.
>>> import gfg
>>> res = fact(5)
>>> res
120
>>> res = my_mod(5,2)
>>> res
1
>>> gfg.cvar.myvar
3.4
Here C variables are accessed as module.cvar.var_name.
Compiling and Linking using distutils
Instead of typing in commands and figuring out what compilation options are needed to compile files, we can automate this using distutils. Create a setup.py as below –
from distutils.core import setup, Extension
name = "gfg"
version = "1.0"
ext_modules = Extension(name = '_gfg' ,sources = [ "gfg.i" , "gfg.c" ])
setup(name = name,
version = version,
ext_modules = [ext_modules])
|
Now write following commands to compile and install module –
$ python setup.py build_ext --inplace
It should look something like this on terminal –

Possible Alternatives
Obviously, SWIG is not the only way for creating wrappers, one can consider following alternatives based on their requirements –
In next article, we will see how to create wrapper for C++ code (OPP)
References
Similar Reads
Using C codes in Python | Set 1
Prerequisite: How to Call a C function in Python Let's discuss the problem of accessing C code from Python. As it is very evident that many of Pythonâs built-in libraries are written in C. So, to access C is a very important part of making Python talk to existing libraries. There is an extensive C p
4 min read
Issues with using C code in Python | Set 1
Prerequisite: Using C codes in Python | Set 1, Set 2 Issue #1 : If using ctypes then there is a problem that the original C code may use language that donât map cleanly to Python. Let's take the example of divide() function as it returns a value through one of its arguments. It is a common C techniq
2 min read
Using C codes in Python | Set 2
Prerequisite: Using C codes in Python | Set 1 In the previous article, we have discussed how to access C code in Python. Now, let's see how to access C functions. Code #1 : Accessing C functions with Python import work print ("GCD : ", work.gcd(35, 42)) print ("\ndivide : ", work
2 min read
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
4 min read
Issues with using C code in Python | Set 2
Prerequisite: Issues with using C code in Python | Set 1 The DoubleArrayType class can handle the situation of Python having different forms like array, numpy array, list, tuple. In this class, a single method from_param() is defined. This method takes a single parameter and narrow it down to a comp
3 min read
Pad or fill a string by a variable in Python using f-string
In Python, we can pad or fill a string with a variable character to make it a specific length using f-strings. We can pad strings to the left, right, or centre by using f-strings with a variable as the padding character. Let's understand with the help of an example: [GFGTABS] Python s = 'GFG
2 min read
Python | C Strings of Doubtful Encoding | Set-1
One can convert strings between C and Python vice-versa but the C encoding is of a doubtful or unknown nature. Let's suppose that a given C data is supposed to be UTF-8, but itâs not being strictly enforced. So, it is important to handle such kind of malformed data so that it doesnât crash Python or
2 min read
Calling Python from C | Set 1
In this article, we will mainly focus on safe execution of a Python callable from C, returning a result back to C and writing C code that needs to access a Python function as a callback. The code below focuses on the tricky parts that are involved in calling Python from C. Code #1 : [Step 1 and 2] O
2 min read
Using Pointers in Python using ctypes
In this article, we are going to learn about using pointers in Python using ctypes module. We will see how we can use Pointers in Python programming language using the ctypes module. Some basic operations like storing addresses, pointing to a different variable using pointers, etc. will be demonstra
10 min read
Convert Text to Speech in Python using win32com.client
There are several APIs available to convert text to speech in python. One of such APIs available in the python library commonly known as win32com library. It provides a bunch of methods to get excited about and one of them is the Dispatch method of the library. Dispatch method when passed with the a
2 min read