Sep 15
The SWIG Wrapper Generator Part 1
SWIG is a C/C++-like language that allows you to export your C/C++ libraries to a number of languages including java, ruby, C#, perl, and others. If you want to export a large library to a particular language or any library to multiple languages SWIG may be what you are looking for. This article does a simple example using swig with java to get you familiar with the concepts. Article 2 will show complex examples dealing with memory management, modifying your API to work in a way that is natural to the target languages and more.
Getting Swig
The first step is to get a copy of SWIG. If you’re on windows then cygwin has an optional swig package and most of the UNIX-style os’s have packages. Of course you can always get it from the SWIG website as well.
Your first interface
This example will introduce you to the basics of what swig does. The next will actually show you how to use it in a more powerful way.
The interface
Basic SWIG is very easy. Let’s suppose you have the following C api (simple.h):
void do_something(int widgetCount);
int do_something_else();
the swig file (simple.i) would look like this:
%module simple
void do_something(int widgetCount);
int do_something_else();
Remarkably similar, yes? In fact the only difference is the module directive. Swig directives all start with the % character and tell the swig compiler how to interpret the specified interface.
Running SWIG
Now that you’ve created your .i file you can run swig on it. In this case we want to export java code so we do the following:
swig -Wall -java simple.i
This will create the following files:
- simple.java – this is the class that you will use to access the API from java.
- simpleJNI.java – This is the JNI class definition (binds to the native function calls)
- simple_wrap.java – This wraps your C code as a JNI interface.
Building the shared C library
The next step is to compile your C code, including the wrapper file you just generated, into a shared library. I’m running with gcc on gygwin so the compile looks like this:
$ gcc -c -I /cygdrive/c/Program\ Files/Java/jdk1.6.0_02/include/ -I /cygdrive/c/Program\ Files/Java/jdk1.6.0_02/include/win32/ simple.c simple_wrap.c
$ gcc -shared simple.o simple_wrap.o -mno-cygwin -Wl,--add-stdcall-alias -o simple.dll
If you are under an actual unix it will look something like (assuming the jdk include directory is in your include path):
$ gcc -c -fpic simple.c simple_wrap.c
$ gcc -shared simple.o simple_wrap.o -o libsimple.so
Writing some Java to interface with your code
So now all we have to do is write some java code to interface with this library:
public class SimpleTest{
public static void main(String[] args){
System.loadLibrary("simple");
simple.do_something(12);
simple.do_something_else();
}
}
Note that the System.loadLibrary call. This is required by java’s JNI API which is what swig uses to bind the C code to your java code. You must call loadLibrary before using the API.
Now all you have to do is compile the java code using javac and then run the program:
$ javac *.java
$ java -Djava.library.path=./ example
Michael Smit is a software engineer in Maryland who currently develops software for spacecraft, spacecraft simulators, and spacecraft control systems.The Author
No Comments
Leave a comment