I was a fan of SWIG some time back when I was developed new python APIs for our test automation framework through that tool, but when I recently revisited the same topic, I was caught unaware as it was not a trivial task like compiling a C or python code and it will do the magic for you, it involved a customized Makefile at that time which I didn't recollect after a long time, fortunately after some experimentation, I was able to come up with a quick documentation on the steps you need to do to make Python-SWIG work on Solaris 10 and above (the platform I in which tested the code).
In this example, we will have a C file with two math functions add and sub, which gets two numbers from the user and outputs the result of addition and subtraction operations respectively, I was also interested in how direct C I/O would work from python, i.e I want the numbers to be input from python shell to C and get the results back and print them, we will see the series of steps required to do the same through SWIG.
| 1. Setting Paths |
| 2. Installing SWIG |
| 3. The C Code |
| 4. The SWIG Interface file |
| 5. Compiling the stuff |
| 6. Running the python module |
This is a simple, yet a crucial step which I want to list first, time and again when I execute the commands required to compile stuff through SWIG, the default path for different utilities were not set, therefore make sure that you have the following locations included in your PATH environment variable (though the /usr/local/bin will make sense only after you install SWIG).
export PATH=$PATH:/usr/ccs/bin:/usr/sfw/bin:/usr/local/bin:
All I would say is is ld, make utilities are in /usr/ccs/bin, gcc (the compiler I used) would be in /usr/sfw/bin and swig (would be) installed in /usr/local/bin.
Now we are all set to install SWIG.
Feel free to skip this step if you already installed one, else you can follow the SWIG web-page for detailed instructions or a short step-by-step summary mentioned below.
1. Download swig 1.3.21 (the one I used for compiling this code) here.
2. gzip -d swig-1.3.21.tar.gz
3. tar -xf swig-1.3.21.tar
4. cd SWIG-1.3.21 (the un-tared directory)
5. ./configure
6. make
7. make install
I am very sure that by the time you read this line, you should have successfully installed SWIG (in /usr/local/bin), for installing the latest version of SWIG follow the appropriate instructions from the SWIG web-page.
Again, another trivial section, I am listing the C Code which is used to do math operations add and sub, which will add and subtract two numbers input by the user.
Listing 1: math_io.c
1. // math_io.c 2. // A Sample Addition Program in C with I/O to be called from python 3. // Author: S.Prasanna 4. 5. #include6. 7. int a, b; 8. 9. // Add two numbers and return result 10. int add() { 11. printf("Addition: Enter two numbers:"); 12. scanf("%d", &a); 13. scanf("%d", &b); 14. return a + b; 15. } 16. 17. // Subtract two numbers and return result 18. int sub() { 19. printf("Subtraction: Enter two numbers:"); 20. scanf("%d", &a); 21. scanf("%d", &b); 22. return a - b; 23. }
I hope the above code doesn't deserve an explanation, does it?
4. The SWIG Interface file
Till now you had an easy ride, now the real work starts, you need to have a SWIG interface file for the C code you wrote above through which the python module will be generated which will call the C functions, our SWIG interface definition is quite simple, right now its good enough if you understand that we are declaring the functions add and sub in the SWIG interface file to be accessed from python, for more details on how SWIG works, do look at this paper on SWIG.
Listing 2: math_io.i
In the above code, the SWIG interface file defines a module math_io (line 5) to be accessed from python which will call the functions add and sub (lines 7 - 8 and 11 - 12).
1. /* math_io.i */ 2. /* SWIG interface file for math_io.c */ 3. /* Author: S.Prasanna */ 4. 5. %module math_io 6. %{ 7. extern int add(); 8. extern int sub(); 9. %} 10. 11. extern int add(); 12. extern int sub();Explanation:
In the above code, the SWIG interface file defines a module math_io (line 5) to be accessed from python which will call the functions add and sub (lines 7 - 8 and 11 - 12).
5. Compiling the stuff
Note that the shared library is named _math_io.so (the naming conventions are important to access the right shared library module from python).I am assuming that you have math_io.c (C source code) and math_io.i (SWIG interface file) in a directory (say /swig-example) with the PATH set as mentioned above, to compile the code, follow the below steps. (the commands are indicated in bold italics)
Note: I used python 2.3 to compile the above code, you need to point to the location of Python.h and other dependencies based on the python interpreter version installed in your system (change the above directory after the -I option supplied to gcc accordingly).
Finally generate the shared library module to access the C functions from python.
bash-3.00# pwd /swig_example bash-3.00# ls math_io.c math_io.i bash-3.00# swig -python math_io.i bash-3.00# ls math_io.c math_io.i math_io.py math_io_wrap.cAfter the first command (swig -python math_io.i), we see a python file (math_io.py) and a C wrapper file (math_io_wrap.c) generated by SWIG.
bash-3.00# gcc -c -I/usr/sfw/include/python2.3/ math_io.c math_io_wrap.c bash-3.00# ls math_io.c math_io.i math_io.o math_io.py math_io_wrap.c math_io_wrap.o bash-3.00#Now we compile math_io.c and the SWIG generated wrapper C source file math_io_wrapper.c which results in two object files math_io.o and math_io_wrap.o.
Note: I used python 2.3 to compile the above code, you need to point to the location of Python.h and other dependencies based on the python interpreter version installed in your system (change the above directory after the -I option supplied to gcc accordingly).
Finally generate the shared library module to access the C functions from python.
bash-3.00# ld -G math_io.o math_io_wrap.o -o _math_io.so bash-3.00# ls _math_io.so math_io.c math_io.i math_io.o math_io.py math_io_wrap.c math_io_wrap.o
6. Running the python module
The easiest part after doing all the hard work, to access the C functions from python.
bash-3.00# python Python 2.3.3 (#1, Nov 22 2005, 01:28:00) [C] on sunos5 Type "help", "copyright", "credits" or "license" for more information. >>> import math_io >>> dir(math_io) ['__builtins__', '__doc__', '__file__', '__name__', '_math_io', '_newclass', '_object', '_swig_getattr', '_swig_setattr', 'add', 'sub'] >>> math_io.add() Addition: Enter two numbers:6 2 8 >>> >>> math_io.sub() Subtraction: Enter two numbers:6 2 4 >>> >>> ^D bash-3.00#Hope you went through this exercise without much trouble, as I mentioned earlier I tested the above steps on Solaris 10, but should work with any Solaris installation.




3 comments:
Thanks for quick tutorial. It helped me get an idea of what SWIG is and how it interfaces with C libraries.
Hi,
I was impressed with the details here, can you please help me answer below query -
I would like to know hot to pass address reference to ‘c’ function through python. I am using swig for ‘c’ anf python interfacing
Interface file : stud.i
***************************************************
%module stud
%header%{
#include "stud.h"
%}
%include "stud.h"
%array_functions(char *,charp );
%inline %{
extern int parse1(char *,char *,char **);
%}
%inline %{
int print_args(char **argv) {
int i = 0;
for(i=0;i<=180;i++) {
printf("argv[%d] = %c\n", i,*(argv[i]));
i++;
}
return i;
}
%}
**********************************************************
Stud.c
======================================
#include string.h
#include stdio.h
/*the angular braces are removed as here as they were causing issues in posting*/
#include "stud.h"
int parse1(char *s, char *p,char **t)
{
strcat(p,s);
*t=&p[0];
}
**********************************************************
Stud.h
===================================
int parse1(char *,char *,char **);
**************************************************
>>> from stud import *
>>> a='rajashree'
>>> c='thoratf'
>>> d=new_charp(1000)
>>> parse1(a,c,d)
2300188
>>> d
Swig Object of type 'char **' at 0x28aca0
Now I want read value of d in python… How do I do it.
Any type of help is appreciated.
Thanks,
Rajashree.
rthorat@starentnetworks.com
Hi i'm not able to install SWIG in cygwin. When i go for 'make install' command then i'm getting error has
make: /cygdrive/c/SWIG-1.3.24/Tools/config/install-sh: command not found
make: *** [install-main] error 127
Pls give me solution for how to fix it.
Thank u
Post a Comment