Java Native Interface (JNI)
The Java Native Interface (JNI) is a framework that allows Java code running in a Java Virtual Machine (JVM) to call and to be called by native applications and libraries written in other languages.
Purpose
Handle situations when an application cannot be written entirely in the Java.
1. Standard Java class library does not support the platform-specific features.
2. Used for time-critical calculations or operations like solving complicated mathematical equations.
3. Using existing native applications and libraries.
Drawback
1. Losing some features of Java: the platform portability and type-safe and secure..
2. The JNI framework does NOT provide any automatic garbage collection for non-JVM memory resource allocated by native side.
3. Error checking is a MUST or it has the potential to crash the JNI side and the JVM.
Overview
This is the procedure of the Java code to call c library through JNI.
Step in writing and running a program.
HelloWorld.java
class HelloWorld {
private native void print();
static {
System.loadLibrary("HelloWorld");
}
public static void main(String[] args) {
new HelloWorld().print();
}
}
Creating HelloWorld.class by compiling, javac HelloWorld.java
Using javah to create the JNI header file of c code
javah -jni HelloWorld
HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
The tool of checking the Signature of each method:
javap –c –p HelloWorld
HelloWrold.c
#include
#include
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
Build the binary and shared library
gcc HelloWorld.c –c –I/[JDK PATH]
gcc –shared –o libHelloWorld.so HelloWorld.o
Finally, execute it!
javac HelloWorld
Native Method Arguments
The JNIEnv is the interface pointer, points to a location that contains a pointer to a function table. Each entry in the function table points to a JNI function.
Mapping of Types
There are two kinds of types in the Java: primitive types and reference types.
The mapping of primitive type is straightforward. The JNI passes objects to native methods as opaque references. The native code must access via the appropriate JNI functions.
JNIEXPORT jstring JNICALL Java_Prompt_getLine
(JNIEnv *env, jobject obj, jstring prompt)
{
char buf[128];
const jbyte *str;
str = (*env)->GetStringUTFChars(env, prompt, NULL);
if(str == NULL) {
return NULL;
}
printf("%s", str);
(*env)->ReleaseStringUTFChars(env, prompt, str);
/* We assume here that the user does not type more than
* 127 characters */
scanf("%s", buf);
return (*env)->NewStringUTF(env, buf);
}
Reference:
Java Native Interface: Programmer's Guide and Specification
Java Native Interface - Wikipedia
The JavaTM Virtual Machine Specification
留言