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:
2. Another useful link using SWIG
3. More on ctypes from Python document
