I'm new to JNI. I have been given an assignment (not for homework--this is real life) to create a Java wrapper API for an existing C API. The C API is currently deployed only on Windows, but versions exist for Linux/Unix platforms, so the solution should be, as much as possible, portable.
I've skimmed through a number of online tutorials and references, but I am having a difficult time discerning a "best practice" for certain things, and I can't find references at all for certain of my issues. Any pointers to books or web sites would be appreciated, as would your own wisdom.
Here are a few of the questions I have (with the answers I have come up with, where I have a glimmer of an idea):
1. Standard mapping of primitive C types to Java. Some are easy--32 bit signed int maps to the Java int type in an obvious way, but some are more difficult. In particular, for an unsigned int, should I use a Java long to capture the full range of values available to a uint, or should I use a "wrapper object" to hold the 4-bytes and provide appropriate accessor methods for the rare cases where I need the value (the C API uses uint mainly for handles to objects it keeps in memory, so the value is unimportant).
2. Mapping 'char *' arguments to StringBuffer. Where the C API uses 'char *' argument to return a (null-terminated) array of characters, I believe the Java side should pass a StringBuffer. Is this correct?
3. Other pointer-to-primitive return values. The C API also uses pointers to primitives to return values to the caller. StringBuffer is a convenient type for null-terminated character arrays, but what about 'int *' or other pointer types? Should I write a class called something like IntegerHolder that can be populated using a field-accessor in the native code? Is there a better way?
Oh, and does anyone have any experience using SWIG to generate the JNI code? Does it do a reasonable job?
I think that's it for now. Thanks for any advice you can provide.
For the benefit of anyone else who's doing this kind of thing, thought I'd reply to my own post with what we ended up doing.
We're using JNA, which is a very nifty solution for this particular problem. For the fairly simple set of methods we need to access, it is a very elegant (not to mention very easy to implement) wrapper.