Black God

How to use C library in python? (Generating Python wrappers for C library)

Update: Thanks to reddit readers, I have updated this write-up with ctypes also.

This is a simple example to quick learn how to generate a python wrapper for C library.  I don’t explain more. Just code example and console output should be sufficient to get the point. Here we have a shared library called flags (flags.c + flags.h) which needs to be accessed from a python script. The first method uses native Python module called ctypes, which is damn simple but available from Python 2.5 only. Another method uses SWIG tool, SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages.

Method-1: Using ctypes

This method is native and available from Python version 2.5. It is just cake walk, no special efforts needed, just load the library and use it.

Step-1: Write a simple C library for learning purpose as shown below

/* flags.c – Source file */

#include <stdio.h>
#include “flags.h”

int gFlag = 0;

void welcome_msg(char *msg) {
printf(“%s\n”, msg);
return;
}

int get_flag() {
return gFlag;
}

void set_flag(int flag) {
gFlag = flag;
return;
}

 

/* flags.h – Header file */

void welcome_msg(char *msg);
int get_flag();
void set_flag(int flag);

Step-2: Here is how to build a shared library (shared object in linux term)

gcc -Wall -fPIC -c flags.c
gcc -shared -Wl,-soname,libflags.so.1 -o libflags.so flags.o

Step-3: Here is how to use this library called libflags.so.

First we need to import ctypes module. And then load the C library using CDLL function. That is it. Here is my console output.

[blackgod@localhost swig-example]$ python
Python 2.6.6 (r266:84292, Dec  7 2011, 20:38:36)
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>> from ctypes import *
>>> mylib = CDLL(“./libflags.so”)
>>> mylib.welcome_msg(“Hi C, I am from Python!”)
Hi C, I am from Python!
24

Method-2: Using SWIG tool

Here we need to write a very simple interface file called pyflags.i, which will be used by SWIG. For the sake of clarity I have given the steps needed to build python wrapper shared object in a simple script called build-python-wrapper-so.sh.

Step-1: Write a simple C library for learning purpose as shown below

/* flags.c – Source file */

#include <stdio.h>
#include “flags.h”

int gFlag = 0;

void welcome_msg(char *msg) {
printf(“%s\n”, msg);
return;
}

int get_flag() {
return gFlag;
}

void set_flag(int flag) {
gFlag = flag;
return;
}

 

/* flags.h – Header file */

void welcome_msg(char *msg);
int get_flag();
void set_flag(int flag);

Step-2: Write a interface file as shown below for the above C library

/* pyflags.i – interface file */
%module flags_wrap
%{
#include “flags.h”
%}

%include “flags.h”

Step-3: The following three commands takes pyflags.i as input file and generates output file _flags_wrap.so. These commands can be executed in shell or put them in a simple shell script.

# Steps to build python wrapper – build-python-wrapper-so.sh
swig -python pyflags.i
gcc -fPIC -c flags.c pyflags_wrap.c -I/usr/include/python2.6
ld -shared flags.o pyflags_wrap.o -o _flags_wrap.so

Step-4: Now you are ready with python module to access your C library. Here is a python console session on how to access the C functions and data from a python script.

blackgod@blackbox ~/Workspace/swig-example $ python
Python 2.6.7 (r267:88850, Jul 10 2011, 08:11:54)
[GCC 4.6.1] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import flags_wrap
>>> print flags_wrap.welcome_msg(“Hi C, I am from Python”)
Hi C, I am from Python
None
>>> flags_wrap.set_flag(1)
>>> print flags_wrap.get_flag()
1
>>>

Reference:

1. SWIG Tutorial

2. Another useful link using SWIG

3. More on ctypes from Python document

 

Leave a Reply

Your email address will not be published. Required fields are marked *