tags:

views:

181

answers:

1

Which of the following (or other) method would you recommend for accessing a C++ shared library from Java and why?

  1. JNI: I hear this has a number of pitfalls and is quite the undertaking?
  2. SWIG: Apparently this makes using JNI easier, but I've heard it has some problems too?
  3. JNA: I could write a C interface and then use JNA with it instead, which is apparently significantly easier than JNI?
  4. CNI: Apparently this is easier than JNI?
  5. Another library: it can't be commercial and I'd prefer something that is still well maintained (this would throw out JNIEasy, JNative, and JACE - I think).

I'm trying to go for minimal development time and problems down the road. Any info on pros/cons of each of these would be appreciated.

EDIT: Optimally, I'd be able to use my C++ objects in Java, but as I mentioned in #3, I could write a C interface using just functions if absolutely necessary. The C++ interface I'd like to have available in Java is something like:

class MyObj1
{
    MyObj1(std::string, bool);
    bool Func1();
    void Func2(bool);
}

class MyObj2
{
    MyObj2(MyObj1*);
    ssize_t Func(uint8_t *, size_t, MyObj1);
}

The actual interface is a bit more complicated, but this demonstrates the type of objects and methods I'll be using. Some of the objects are derived, but the Java interface does not need to have any polymorphic behavior.

+3  A: 

For Java->C++, I've used JNI, JNA and played with SWIG.

JNA is the easiest to use, but as you note, requires hand-writing a C interface to the C++ API. It can also be slower than JNI by an order of magnitude. However, I measured individual calls at a few hundred nanoseconds on one machine, so that's unlikely to matter except in a bottleneck.

JNA redundantly specifies C function signatures, in Java. JNI can redundantly specify Java function signatures, in C strings. Discrepancies in either can result in unexpected runtime behavior.

I personally would use JNA unless the interface is complex enough to make hand-writing the C interface cumbersome for you, or the individual calls are more than a few hundred nano seconds.

This week I've been faced with such an exception -- a rich C++ interface with many classes and methods. I've started playing with SWIG, and it's looking promising. It's been fairly easy to use, and automatically generates the Java bindings and C implementation. Smart pointers did take a little extra work -- you have to instruct SWIG to instantiate the templates.

Andy Thomas-Cramer
+1 for good concise, yet detailed answer. I'm still wondering whether CNI might be the way to go though. I'm working exclusively on Linux with GCC and apparently it can do C++ and is easier. Thanks again.
deuberger
@deuberger - Hope it works well for you. Sounds like its non-portability is not a problem for you. At a glance, it looks like it requires you to hand-write some C++ glue, which could be little work for a small interface.
Andy Thomas-Cramer