SWIG stands for Simplified Wrapper and Interface Generator.
SWIG is used to simplify the task of interfacing different languages to C and C++ programs.
For our discussion, in this article we will explain how to use SWIG to interface from Perl to C programs.
Some may think, why would one write Perl programs and call a C function from it? The answer to this lies in the strength of C/C++ programs, which is performance. A developer may choose to code in Perl/Python, because it is lot easier to design GUI using these languages and also the language itself takes care of memory allocation/de-allocation.
So, lets review the basics of SWIG. First we need to write a C program, which we want to access it from Perl. Then we need to write an ‘interface’ file for the C program.
Step 1: Creating the C program
area.c
double pi = 3.14; int area_of_square(int n) { return (n*n); } double area_of_circle(int r) { return (pi * (r*r)); }
Step 2: Creating the Interface File
Interface file are the one which is used by SWIG to provide wrapper files. The basic interface file should include all the prototypes of the function and variables. Each interface file will have a ‘module’ directive and ‘module name’ followed by it. Interface files are created with ‘.i’ extension.
area.i
%module area %{ extern double pi; extern double area_of_circle(int r); extern int area_of_square(int n); %} /* If we don't want to access pi variable from the perl, then comment the below line. */ extern double pi; extern int area_of_square(int n); extern double area_of_circle(int r);
Once the interface file is ready, then with appropriate compilation steps, we can create wrapper for almost any languages, and from those languages we can access the functions written in C.
Step 3: Swig Compilation for Perl
swig -perl5 area.i
It creates 2 files, area_wrap.c and area.pm.
gcc -fpic -c -Dbool=char -I/usr/lib/perl/5.10.1/CORE area_wrap.c area.c -D_GNU_SOURCE
It compiles the area_wrap.c and area.c and creates area.o and area_wrap.o object files. The path given in -I may vary depending on the version, and installation path used when installing perl.
Now we need to create a shared object file as follows.
gcc -shared area.o area_wrap.o -o area.so
A new shared object file, named area.so will be created.
Now we can write a Perl program to access the functions written in C.
area.pl
#!/usr/bin/perl use strict; use warnings; use area; my $area_of_cir = area::area_of_circle(5); my $area_of_squ = area::area_of_square(5); print "Area of Circle: $area_of_cir\n"; print "Area of Square: $area_of_squ\n"; print "$area::pi\n";
Now when we run this Perl program, it uses the ‘area.pm’ file (use area;), which loads the shared object file using ‘DynaLoader’, and calls the C program.
You can also say a variable in C is readonly by using ‘%immutable;’ directive, so that from Perl you can’t modify the variable. In our previous example, the variable ‘$area::pi’ can be changed, which in-turn affects the ‘area_of_circle’ function, which uses the ‘pi’ variable for calculation. The interface file will look like,
area.i
%module area %{ extern double pi; extern double area_of_circle(int r); extern int area_of_square(int n); %} %immutable; extern double pi; %mutable; /* Optional */ extern int area_of_square(int n); extern double area_of_circle(int r);
Now from Perl, if we try to assign a new value to the ‘pi’ variable, it will throw an error.
By using the same interface file, we can create a wrapper for Python as explained below.
Steps for Creating Python Interface
#> swig -python area.i #> gcc -fpic -c -Dbool=char -I/usr/include/python2.6 area.c area_wrap.c #> gcc -shared area.o area_wrap.o -o _area.so #>python >>>import area >>>area.area_of_square(5) 25
Many open source and commercial software uses SWIG, so that they will write the core module in C, and let any person using any language to use their modules with the help of SWIG.
Comments on this entry are closed.
Thanks!!
Learnt something new today.
Very nice!! Didn’t know about this one. Well written..
Thank you so much!
Very informative article. Opens up many new doors in Perl.