14 August 2011

Java Native Access (JNA) by Example..

Java Native Access is a mean by which you can call native code (C/CPP) from your java programs.

It is intend is to remove the plumbing code when using JNI..

Let's write a simple example together..

First, let's write the Native (CPP) library:
#include <iostream>

extern "C" __declspec(dllexport) 
int add (int x, int y)
{
    return x + y;
}

(Don't ask me what this line "extern "C" __declspec(dllexport)
" means, you can read in wikipedia about each term, but what you need to know, it is required to be included in our code to be able to export it to a DLL library)

Let's generate the DLL from the above source code:
g++ -c add.cc
dir add.o
g++ -shared -o add.dll add.o
dir add.dll

Now we have the file "add.dll", we need to export its contents to see whether the our "add" function is being exported or not.

There's a yet simple but powerful tool called dependencywalker
.. download it and open the dll file using it. (as shown below)

Now Let's write the Java program that will call this native function ..

You will need to download the jar file of jna library..
Download it from here.

Open Eclipse and create a new Java Project and name it as "AddJNAExample".
put the file "jna.jar" and put it in the project build path in eclipse.. and come to write the source code for the program.


package com.daz;

import com.sun.jna.Library;
import com.sun.jna.Native;

public interface Add extends Library
{
    Add INSTANCE = (Add) Native.loadLibrary("add", Add.class);
    int add(int x, int y);
}

And Here's the Driver:

package com.daz;

public class Test {
    public static void main(String[] args) {
        Add lib = Add.INSTANCE;
        System.out.println(lib.add(10, 20));
    }
}

Note, If you run it now, the following exception will be thrown:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'add': The specified module could not be found.

This is because, you will need to specify the dll library to the jvm as follows:

java -Djna.library.path="D:\dlls\add.dll" com.daz.Test

The result will be:
30

JNA involves more complex type-mappings ...

References:
http://www.cygwin.com/cygwin-ug-net/dll.html
http://today.java.net/pub/a/today/2009/05/19/protect-your-legacy-code-jna.html
http://www.dependencywalker.com/

Post a Comment