Posts
Search
Contact
Cookies
About
RSS

JNA wrapping C libraries for Java the easy way!

Added 29 Mar 2015, 3:46 p.m. edited 19 Jun 2023, 3:09 a.m.
While wrapping a simple library for C isn't exactly rocket science, it has its issue and can be a pain, there are numerous build systems (many seemingly making it a more complex job) but often you find its just not fun! A really nice alternative is to use JNA which allows you to write a wrapper coding solely in Java, there is a performance hit but this is often a moot point, for example even in a video game some libraries like GLFW might only need a dozen or so calls a frame, so if it takes a little longer its not a game breaking deal. I might however consider keeping my JNI based GLES 2.0 wrapper as on a slow machine an overhead on potentially a hundred or so calls could have an impact. While JNA has a lot of advanced features like direct coupling of C structures with Java classes and even handling callbacks, lets look at a very simple example to see just how easy it is...
public static class GLFW3 {
    static {
        Native.register("glfw");
    }

    public static native int         glfwInit();     
    public static native Pointer     glfwCreateWindow(
                                            int width, int height,
                                            String title,
                                            Pointer monitor,
                                            Pointer share );
    public static native void        glfwTerminate();    
    public static native void        glfwMakeContextCurrent( Pointer window);         
    public static native int         glfwWindowShouldClose( Pointer window);
    public static native void        glfwSwapBuffers( Pointer window);
    public static native void        glfwPollEvents();             
}
Even for such simple use doing this in JNI would consist of some C code and a Makefile and hopefully an ant build script which would give you a target to generate the needed C header files... or you can write a few lines of Java... Actually using these functions is fairly straight forward too
window = GLFW3.glfwCreateWindow(640, 480, "Hello World", Pointer.NULL , Pointer.NULL);
                
if (Pointer.nativeValue(window)==0) {
    GLFW3.glfwTerminate();
    System.out.println("unable to create glfw window");
    System.exit(-1);
}
This is a piece of a simple test I put together to test JNA as you can see its simple to see whats going on and converting some C code that uses the library is fairly trivial. To test out JNA I wrapped just enough functions from GLFW and GLES 2.0 to make a window with a flashing coloured background. You'll need libglfw.so and libGLESv2.so on your library path, but you could as easily use GL if your platform doesn't have GLES available. You can get the complete test here jna-test.tar.gz