Sep 15

The SWIG Wrapper Generator Part 1

Category: Programming

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

The Author

Michael Smit is a software engineer in Seattle, Washington who works for amazon

Comments are off for this post

Comments are closed.