SWIG is a little nice glue tool that connects programs written in C and C++ with a variety of high-level programming languages like Javascript, Perl, PHP, Python, Tcl, Ruby, Java etc… It is similar to JNI in Java world.
It is available in most linux distribution. In ubuntu, it can be installed using “ sudo apt-get install swig”.
By looking the following example, you will see it is pretty straightford to make the service implemented in C, C++ available to TCL, Python, Java.
Assume you have services implemented in the following C file
See below services.c :
/* File services.c */
#include <time.h>
#include <math.h>
double temperature = 27 . 5 ; /* Celcius */
/* Find the current time and return as ASCII text */
char * get_time () {
time_t localTime ;
time ( & localTime );
return ctime ( & localTime );
}
double square_root ( double a ) {
return sqrt ( a );
}
Define the services interface in SWIG way: services.i
/* services.i */
% module services
% {
/* Put header files here */
extern double temperature ;
extern char * get_time ();
extern double square_root ( double a );
% }
extern double temperature ;
extern char * get_time ();
extern double square_root ( double a );
Now we have the following:
weng@weng-u1604:~/swig/python$ ls -l
total 8
-rw-rw-r-- 1 weng weng 308 Aug 6 16:57 services.c
-rw-rw-r-- 1 weng weng 256 Aug 6 16:57 services.i
weng@weng-u1604:~/swig/python$
1. Access the services from Python
First make sure you have python-dev package installed (sudo apt-get install python-dev )
1.1 Compiling the interface to generate the stub for python:
weng@weng-u1604:~/swig/python$ swig -python services.i
weng@weng-u1604:~/swig/python$ ls -l
total 128
-rw-rw-r-- 1 weng weng 308 Aug 6 16:57 services.c
-rw-rw-r-- 1 weng weng 256 Aug 6 16:57 services.i
-rw-rw-r-- 1 weng weng 2746 Aug 6 17:13 services.py
-rw-rw-r-- 1 weng weng 114799 Aug 6 17:13 services_wrap.c
weng@weng-u1604:~/swig/python$
After compilation of interface file, a file named “services_wrap.c” and “services.py” are generated.
1.2 Build into object files to create shareable library
weng@weng-u1604:~/swig/python$ gcc -fPIC -c services.c services_wrap.c -I /usr/include/python2.7
weng@weng-u1604:~/swig/python$ ld -shared services.o services_wrap.o -o _services.so
weng@weng-u1604:~/swig/python$ ls -l
total 232
-rw-rw-r-- 1 weng weng 308 Aug 6 16:57 services.c
-rw-rw-r-- 1 weng weng 256 Aug 6 16:57 services.i
-rw-rw-r-- 1 weng weng 1824 Aug 6 17:20 services.o
-rw-rw-r-- 1 weng weng 2746 Aug 6 17:13 services.py
-rwxrwxr-x 1 weng weng 48968 Aug 6 17:20 _services.so
-rw-rw-r-- 1 weng weng 114799 Aug 6 17:13 services_wrap.c
-rw-rw-r-- 1 weng weng 51544 Aug 6 17:20 services_wrap.o
weng@weng-u1604:~/swig/python$
Now “_services.so” is available to be used for Python. It is loaded by services.py file, and it is assumed to be in the same directory as services.py file for it to be loaded properly.
We can test it.
1.3 Testing
eng@weng-u1604:~/swig/python$ python
Python 2.7.12 ( default, Jul 1 2016, 15:12:24)
[ GCC 5.4.0 20160609] on linux2
Type "help" , "copyright" , "credits" or "license" for more information.
>>> import services
>>> services.get_time()
'Sat Aug 6 17:25:11 2016\n'
>>> services.square_root( 4)
2.0
>>> services.square_root( 100.1)
10.00499875062461
>>>
2. Access the services from TCL
First make sure you have python-dev package installed (sudo apt-get install tcl-dev)
2.1 Compiling the interface to generate the stub for TCL:
weng@weng-u1604:~/swig/tcl$ ls -l
total 8
-rw-rw-r-- 1 weng weng 308 Aug 6 17:34 services.c
-rw-rw-r-- 1 weng weng 256 Aug 6 17:34 services.i
weng@weng-u1604:~/swig/tcl$ swig -tcl services.i
weng@weng-u1604:~/swig/tcl$ ls -l
total 72
-rw-rw-r-- 1 weng weng 308 Aug 6 17:34 services.c
-rw-rw-r-- 1 weng weng 256 Aug 6 17:34 services.i
-rw-rw-r-- 1 weng weng 65520 Aug 6 17:35 services_wrap.c
weng@weng-u1604:~/swig/tcl$
2.2 Build into object files to create shareable library
weng@weng-u1604:~/swig/tcl$ gcc -fPIC -c services.c services_wrap.c -I /usr/include/tcl
weng@weng-u1604:~/swig/tcl$ ld -shared services.o services_wrap.o -o services.so
weng@weng-u1604:~/swig/tcl$ ls -l
total 144
-rw-rw-r-- 1 weng weng 308 Aug 6 17:34 services.c
-rw-rw-r-- 1 weng weng 256 Aug 6 17:34 services.i
-rw-rw-r-- 1 weng weng 1824 Aug 6 17:39 services.o
-rwxrwxr-x 1 weng weng 30864 Aug 6 17:39 services.so
-rw-rw-r-- 1 weng weng 65520 Aug 6 17:35 services_wrap.c
-rw-rw-r-- 1 weng weng 34280 Aug 6 17:39 services_wrap.o
weng@weng-u1604:~/swig/tcl$
Now “services.so” is available to be used for TCL. We can test it.
2.3 Testing
weng@weng-u1604:~/swig/tcl$ tclsh
% load ./services.so services
% puts $temperature
27.5
% get_time
Sat Aug 6 17:46:11 2016
% square_root 10.1
3.1780497164141406
% weng@weng-u1604:~/swig/tcl$
3. Access the services from Java
First make sure you have JDK package installed.
3.1 Compiling the interface to generate the stub for Java:
weng@weng-u1604:~/swig/java$ ls -l
total 8
-rw-rw-r-- 1 weng weng 308 Aug 6 17:50 services.c
-rw-rw-r-- 1 weng weng 256 Aug 6 17:50 services.i
weng@weng-u1604:~/swig/java$ swig -java services.i
weng@weng-u1604:~/swig/java$ l s-l
ls : cannot access s-l: No such file or directory
weng@weng-u1604:~/swig/java$ ls -l
total 24
-rw-rw-r-- 1 weng weng 308 Aug 6 17:50 services.c
-rw-rw-r-- 1 weng weng 256 Aug 6 17:50 services.i
-rw-rw-r-- 1 weng weng 752 Aug 6 17:50 services.java
-rw-rw-r-- 1 weng weng 633 Aug 6 17:50 servicesJNI.java
-rw-rw-r-- 1 weng weng 7697 Aug 6 17:50 services_wrap.c
weng@weng-u1604:~/swig/java$
3.2 Build into object files to create shareable library
weng@weng-u1604:~/swig/java$ gcc -fPIC -c services.c services_wrap.c -I /opt/jdk18/include/ -I /opt/jdk18/include/linux/
weng@weng-u1604:~/swig/java$ ls -l
total 32
-rw-rw-r-- 1 weng weng 308 Aug 6 17:50 services.c
-rw-rw-r-- 1 weng weng 256 Aug 6 17:50 services.i
-rw-rw-r-- 1 weng weng 752 Aug 6 17:50 services.java
-rw-rw-r-- 1 weng weng 633 Aug 6 17:50 servicesJNI.java
-rw-rw-r-- 1 weng weng 1824 Aug 6 17:52 services.o
-rw-rw-r-- 1 weng weng 7697 Aug 6 17:50 services_wrap.c
-rw-rw-r-- 1 weng weng 3464 Aug 6 17:52 services_wrap.o
weng@weng-u1604:~/swig/java$ gcc -shared services.o services_wrap.o -o services.so
weng@weng-u1604:~/swig/java$ ls -l
total 48
-rw-rw-r-- 1 weng weng 308 Aug 6 17:50 services.c
-rw-rw-r-- 1 weng weng 256 Aug 6 17:50 services.i
-rw-rw-r-- 1 weng weng 752 Aug 6 17:50 services.java
-rw-rw-r-- 1 weng weng 633 Aug 6 17:50 servicesJNI.java
-rw-rw-r-- 1 weng weng 1824 Aug 6 17:52 services.o
-rwxrwxr-x 1 weng weng 12896 Aug 6 17:52 services.so
-rw-rw-r-- 1 weng weng 7697 Aug 6 17:50 services_wrap.c
-rw-rw-r-- 1 weng weng 3464 Aug 6 17:52 services_wrap.o
weng@weng-u1604:~/swig/java$ pwd
/home/weng/swig/java
weng@weng-u1604:~/swig/java$
3.3. Testing
weng@weng-u1604:~/swig/java$ cat Main.java
public class Main {
public static void main( String argv[]) {
String p = System.getProperty( "java.library.path" ) ;
System.out.println( p) ;
System.load( "/home/weng/swig/java/services.so" ) ;
System.out.println( services.square_root( 9)) ;
System.out.println( services.get_time()) ;
}
}
weng@weng-u1604:~/swig/java$ javac Main.java
weng@weng-u1604:~/swig/java$ java Main
:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
3.0
Sat Aug 6 18:09:01 2016
weng@weng-u1604:~/swig/java$