I have a project written in C++ and I'm looking to write a Java GUI as an interface to it. The choice of Java is fixed so I'd need to learn how to be able to call the C++ code from Java. Rewriting the C++ code is not an option. I'd like input on:
Thanks.
I recently worked on a project in which we had to do exactly the same thing. We had a data model written in C++ and needed to put a Java GUI on top. What we ended up doing was identifying the C++ classes that we needed to access from the GUI and used SWIG to generate plain old java classes which wrapped the C++ objects.
The Java classes generated by SWIG have identical interfaces to the C++ classes they are wrapping which means that communicating with the C++ objects, from Java, involves only working with Java objects.
Here is an example:
Given two C++ classes:
class SomeClass {
public:
void foo(SomeOtherClass bar);
SomeOtherClass baz();
}
class SomeOtherClass {
public:
void do();
}
SWIG will generate two Java classes:
public class SomeClass {
public void foo(SomeOtherClass bar);
public SomeOtherClass baz();
}
public class SomeOtherClass {
public void do();
}
Calling C++ objects, from Java, is just like writing regular Java:
SomeClass sc = new SomeClass();
SomeOtherClass soc = sc.baz();
sc.foo(soc);
Line 1: The Java wrapper of SomeClass is instantiated as well as a C++ object of type SomeClass.
Line 2: Calls to the sc instance of SomeClass are forwarded to the C++ instance of SomeClass. The return value of the C++ instance is passed to the Java wrapper and returned by the Java wrapper.
Line 3: SWIG handles converting from the Java wrapper types (or java primitive types) to the underlying C++ types.
SWIG will take care of converting to/from Java/C++ types during method invocations and all the JNI details are hidden away from view :)
The SWIG interface code needed to generate a Java wrapper for a C++ class can be as simple as:
interface.i: { #include "ClassDefinition.h" } %include "ClassDefinition.h"
SWIG is very powerful. Anything you need to do you can do either with the basic features, typemaps, javacode type maps, or directors.
SWIG also allows your C++ code to call your Java objects without any modification to your existing C++ code. This is a feature called "cross language polymorphism." cross language polymorphism essentially lets you create Java classes that subclass C++ classes. You can then pass instances of those Java classes as parameters to C++ method calls. Any invocations, from C++, on the passed in instance will be forwarded back to your Java object. I won't get into the details here, but it isn't terribly complicated once you get over the initial shock of the idea.