Friday, 11 July 2014

Call cpp program from java

The JNI is a native programming interface. It allows Java code that runs inside a Java Virtual Machine (VM) to inter operate with applications and libraries written in other programming languages, such as C, C++, and assembly.

In this post we are going to see how to call a functions written in 'Cpp' in a 'Java' Program. Will see the details step by step.

Step 1 : Will start writing java source code first. Below java file declares native methods and loads the native library.

Example
public class NativeEx{
 public native int square(int n); 
 public native int sum(int[] intArray); 
 
 public static void main(String[] args){
  System.loadLibrary("Example");
  NativeEx sample = new NativeEx();
   
  int square = sample.square(5);
  int sum = sample.sum(new int[]{1,2,3,4,5,6,7} );
   
  System.out.println("square: " + square);
  System.out.println("sum Of Array Data: " + sum);
 }
}

The native keyword used only with methods. The native keyword tells the java compiler that this method is implemented in native code outside of the Java class.
System.loadLibrary("Example")

Above statement loads the shared library 'Example', will see how to generate shared library in step 5.

Step 2: Compile the Java class
javac NativeEx.java

Step 3: Create the header file using javah
Create 'C' header file, which contains native methods signatures. Use javah tool which comes with jdk installation itself.

javah NativeEx


Above command generates NativeEx.h file. The code in NativeEx.h is below.

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

#ifndef _Included_NativeEx
#define _Included_NativeEx
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     NativeEx
 * Method:    square
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_NativeEx_square
  (JNIEnv *, jobject, jint);

/*
 * Class:     NativeEx
 * Method:    sum
 * Signature: ([I)I
 */
JNIEXPORT jint JNICALL Java_NativeEx_sum
  (JNIEnv *, jobject, jintArray);

#ifdef __cplusplus
}
#endif
#endif

Step 4 : Write 'C++' code
Example.cpp
#include "NativeEx.h"

JNIEXPORT jint JNICALL Java_NativeEx_square(JNIEnv *env, jobject obj, jint num){
        return num * num;
}

JNIEXPORT jint JNICALL Java_NativeEx_sum(JNIEnv *env, jobject obj, jintArray array){
        int i, sum = 0;
        jsize len = env->GetArrayLength(array);
        jint *body = env->GetIntArrayElements(array, 0);
        for (i=0; i<len; i++){
                sum += body[i];
        }
        env->ReleaseIntArrayElements(array, body, 0);
        return sum;
}

int main(){
return 0;
}

Step 5: Create Shared Library file

On AIX
cc_r -qmkshrobj -qarch=ppc -I /usr/java5/include -o Example Example.cpp

On Solaris
cc -G -I/usr/local/jdk/include -I/user/local/jdk/include/solaris Example.cpp -o Example.so

On Windows
cl -Ic:\jdk\include -Ic:\jdk\include\win32 -LD Example.c -FeExample.cpp

Step 6: It is time to run the java program.
Java NativeEx

Output
square: 25
sum Of Array Data: 28

Note:
If you got 'UnsatisfiedLinkError' make sure your shared library is in your library path.



                                                             Home

No comments:

Post a Comment