Vous êtes sur la page 1sur 13

An introduction to Java Native

Interface (JNI)

Santhosh Vasudevan
Java Native Interface (JNI)

The Java Native Interface (JNI) is the native programming interface


for Java and is part of the Java development kit (JDK).

JNI allows Java code that runs within a Java Virtual Machine (VM) to
operate with applications and libraries written in other languages,
such as C, C++, and assembly.

Programmers use the JNI to write native methods to handle those


situations when an application cannot be written entirely in the Java
programming language. You may need to use native methods in the
following situations
• The standard Java class library may not support the platform-dependent
features needed by your application.
• You may already have a library or application written in another
programming language and you wish to make it accessible to your Java
applications.
• You may want to implement a small portion of time-critical code in a
lower-level programming language, such as assembly, and then have your
Steps to achieve java native interfacing

• Writing the java code with the native methods

1. Define native methods


public native void <method_name>();

2. Load the library (containing the native implementation)


static {
System.loadLibrary("hello");
}
(Microsoft Windows system converts the same name to
hello.dll)
Steps to achieve java native interfacing

• Creating the header file from the compiled Java code

• Run javah on the compiled java code

This creates a <java_file_name>.h file


Provides a C function signature for the implementation of the
native method
Steps to achieve java native interfacing

• Sample (output)

#include <jni.h>

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL
Java_<Fully_qualified_class_name>_<method_name
> (JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Steps to achieve java native interfacing

• Method Signature

JNIEXPORT void JNICALL


Java_<Fully_qualified_class_name>_<method_name> (JNIEnv*,
jobject);

If class name = calypsox.tk.core.JNInterface


Method name = getValueFromNative()
Then the method signature would be

e.g.,
JNIEXPORT void JNICALL Java_ calypsox_tk_core_JNInterface
getValueFromNative(JNIEnv *, jobject);
Steps to achieve java native interfacing

• Writing the native code

2. The function written must have the same function


signature as the one generated by javah tool
3. Include (#include) the jni.h and the generated *.h file in
the native code implementation. jni.h provides information
that the native language code requires to interact with the
Java runtime system. When writing native methods, you
must always include this file in your native language
source files
Steps to achieve java native interfacing

• Sample code

#include <jni.h>
#include “<generated>.h“
#include <some.h>
JNIEXPORT void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject
obj) {
//…call any function (probably something defined in the
included *.h file – “some.h”)
return;}
Steps to achieve java native interfacing

• Create (dynamic link library) and register the library

1. Build the DLL using the appropriate tool (say Microsoft


Visual C++)

3. Register the DLL (For our class to load the library at


runtime)

The setup is ready to execute the native method from the Java
program after loading the above library (DLL).
Some consideration of data types

Java Type Native Type


boolean jboolean
byte jbyte
char jchar
short jshort
int jint
long jlong
float jfloat
double jdouble
void void

1. int in Java for receiving pointers (Objects).


Typecast pointer to jint and return from c

3. jint & jstring for receiving appropriate value in


c
Some consideration of data types

3. Convert to appropriate native type before


using. E.g., jstringToWindows(JNIEnv, jstring)
to convert to char*

JNIEXPORT jstring JNICALL Java_Prompt_getLine(JNIEnv


*env, jobject obj, jstring prompt) {

printf("%s", prompt); // Would cause a VM
crash

}
Some consideration of data types

Wrong
JNIEXPORT jint JNICALL
Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray
arr)
{
int i, sum = 0;
for (i=0; i<10; i++) {
sum += arr[i];
}
...

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

• Releasing after usage


Finally

If it executes successfully then kudos to you…


Else if you get an exception like this
java.lang.UnsatisfiedLinkError: no <library name> in shared
library path
at java.lang.Runtime.loadLibrary(Runtime.java)
at java.lang.System.loadLibrary(System.java) …
Then maybe the DLL is not registered properly.
If it is registered properly then it should work :o

Thank You

Vous aimerez peut-être aussi