Wednesday, September 14, 2011

Simple JNI Example

This is a simple JNI example on Windows.
Tested with: MingW, Windows XP, Java 6

Create a java file

public class Hello {
    static {

    public native void sayHello();

    public static void main(String args[]) {
        Hello hello=new Hello();

Compile the file and get Hello.class file

Execute the command. This will find native methods in the class and create appropriate declaration in C language in Header file. This will generate Hello.h file

javah -jni Hello

Hello.h file looks like this

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Hello */

#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern "C" {
 * Class:     Hello
 * Method:    sayHello
 * Signature: ()V
JNIEXPORT void JNICALL Java_Hello_sayHello(JNIEnv *, jobject);

#ifdef __cplusplus

Now implement the header file's declared method. For that we have to create a C file.


#include <jni.h>
#include <stdio.h>
#include <conio.h>
#include "Hello.h"

JNIEXPORT void JNICALL Java_Hello_sayHello(JNIEnv * env, jobject jobj)
    printf("Hello World");

We have implemented method in C which is declared as native in Java.
We will compile the C file and generate dll which will be used by Hello.class, see the line System.loadLibrary("hello");

Running the command will generate hello.dll file

gcc -Wl,--add-stdcall-alias -I <JAVA_HOME>/include -I <JAVA_HOME>/include/win32 Hello.c -shared -o hello.dll

"-Wl" is an option with which we can pass linker options to gcc separating by commas.
"--add-stdcall-alias" is a linker option.
The option prevents linker error like: "java.lang.UnsatisfiedLinkError: Hello.sayHello()V".
"-I" will search for included files in specified directories.
"-shared" will generate shared library.
"-o" specifies name of output file.

Now simply run the class file.

java Hello

You might get "Hello World" as output.