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.
The javah program generates C header and source files, which provide the glue for integrating C code with Java. You can use these C header and source files to integrate C++ code into Java as well.
The Java Native Interface (JNI) is a standard to integrate in a portable way C++ and Java code. It works in both directions: you can call a C++ library from Java or you can call Java components from C++.
Now we need some Java code that will use the JNI in order to use the C library. Let's make a Java Counter class which will use the underlying C library. This looks like just another wrapper and it is, unfortunately. JNI can expose C functions that can be called by Java but it cannot expose Java style objects.
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.
http://www.swig.org/
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With