31
Java Native Interface (JNI)

Java Native Interface (JNI)

  • Upload
    chick

  • View
    188

  • Download
    5

Embed Size (px)

DESCRIPTION

Java Native Interface (JNI). JNI. Linking Java and C code. JNI. Stands for “ Java Native Interface ” Set of tools/code that allows user to call “ native ” methods from Java. Includes “ bindings ” for C/C++. Can be used to call C/C++ from Java (typical), or Java from C (invocation API) - PowerPoint PPT Presentation

Citation preview

Page 1: Java Native Interface (JNI)

Java Native Interface (JNI)

Page 2: Java Native Interface (JNI)

JNI

Linking Java and C code

Page 3: Java Native Interface (JNI)

JNI

• Stands for “Java Native Interface”• Set of tools/code that allows user to call “native”

methods from Java.• Includes “bindings” for C/C++.• Can be used to call C/C++ from Java (typical), or Java

from C (invocation API)• Differs from spawning executable – data is passed

to/from C/C++ method• Question: why is this difficult?

Page 4: Java Native Interface (JNI)

Reasons for using JNI

• Feature not available in java language (rare).

• Code already written in another language, don’t want to rewrite (typical).

• Java is slow (how slow?)

• Other language has no additional features per se, but has much better syntax for handling certain operations (Fortran for math).

Page 5: Java Native Interface (JNI)

Problems with JNI

• Only provides C/C++ bindings. Going to Fortran, COBOL, Ada, etc. requires extra step.

• Not portable

• Mapping is not trivial

• Can be unsafe

• Cannot run from applet (security issues)

Page 6: Java Native Interface (JNI)

Machinery for using JNI

Steps to follow …

Page 7: Java Native Interface (JNI)

Basic steps to calling native code

1. Write java class with at least one method declared with native keyword. Provide no implementation– public native void sayHello();– Example above is most simple, but method may pass any

parameters or have any return type.

2. Add a call to System.loadLibrary(“libname”) in the class that declares the native method:– static{

System.loadLibrary(“hello”);}//static means called only once.

Page 8: Java Native Interface (JNI)

Steps, cont.

3. Compile the class– javac Hello.java

4. Produce the C/C++ header files using the javah utility:– Javah Hello– This produces the header file Hello.h

5. Write your implementation file by first copying the function signature produced in the include file. Also, #include the header file.

#include “Hello.h”

Page 9: Java Native Interface (JNI)

Steps, cont.

6. Write the implementation in C/C++. This will require using JNI methods to access the data or possibly casts to convert to basic C/C++ types

7. Best technique: Break into two steps. Think of your C/C++ function as a wrapper which accesses the Java data and maps it to C data using JNI methods, then shoves the converted data into a prewritten standalone C program.

Page 10: Java Native Interface (JNI)

Steps, cont.

8. Compile your native method(s) as a shared object (or DLL on Windows). – WARNING: Be sure to point your linker to the include files

in /jdk1.3/include and jdk1.3/include/linux (for example).– WARNING: Mixing languages is much easier using a

straight C wrapper rather than C++.

9. Set the environment variable LD_LIBRARY_PATH to the shared object directory

• Run main Java class.

Page 11: Java Native Interface (JNI)

C language bindings

What does Java pass to my method?

Page 12: Java Native Interface (JNI)

What does Java pass to my C function?

• JNIEnv* : A pointer to the the JNI environment. This pointer is a handle to the current thread in the JVM, and contains mapping functions and other housekeeping information.

• jobject : A reference to the object that called the native code. (like “this” pointer).

• Any arguments specified by the method.

Page 13: Java Native Interface (JNI)

Simple examples online

• HelloWorld Example: No data passed– Hello.java– Hello.cc

• Max example : Only native dataypes– Utils.java– utils.cc

• Advanced Max example: Arrays– Utils.java– utils.cc

• Max Java-C-Fortran: max.f

Page 14: Java Native Interface (JNI)

Native datatype mappingsJava Type Native Type Size in bitsboolean jboolean 8, unsignedbyte jbyte 8char jchar 16, unsignedshort jshort 16int jint 32long jlong 64float jfloat 32double jdouble 64void void N/a

Page 15: Java Native Interface (JNI)

Java object Mappings

• Object passed by reference• All objects have type jobject as:

Page 16: Java Native Interface (JNI)

Object mappings, cont.

• For example, if a method getLine exists in a class call Prompt, then:private native String getLine(String Prompt);

is mapped intoJNIExport jstring JNICALL Java_Prompt_getLine(JNIEnv *, jobject, jstring);

• But how to access data/methods from object that is passed in?

Page 17: Java Native Interface (JNI)

JNI Advice

• Can seem like a bewildering number of functions. • Do not try to learn it all.• Keep interfaces very simple. – Preferably, only native datatypes, Strings, and arrays.

• Be careful about – Copies vs. rerences– Freeing memory

• Best not to allocate memory from with native code.

Page 18: Java Native Interface (JNI)

Accessing java strings

• Do NOT do the following: JNIEXPORT jstring JNICALL Java_Prompt_getLine(JNIEnv *env,

jobject obj, jstring prompt){ printf(“%s”, prompt); }

• Why is this bad?

Page 19: Java Native Interface (JNI)

Right way to access Strings

• Must use special methods in env structurechar *str = (*env)->GetStringUTFChars(env,prompt,0);/* this maps into regular C char* */

printf(“%s”, str); /* now it is ok to print */

(*env)->ReleaseStringUTFChars(env, prompt, str);/* must release String to avoid memory leaks */

Page 20: Java Native Interface (JNI)

Returning Strings

• Previous technique allows us to use a String passed in from Java.

• What if we want to return a String?• Can use NewStringUTF as:char buf[128]; /* allocate memory for local char* in C */scanf(“%s”, buf); /* read into char* from stdio */return( (*env)->NewStringUTF(env, buf)); /* construct and return the Java String */

Page 21: Java Native Interface (JNI)

Other JNI String methods

• GetStringChars– Takes the Java String and returns a pointer to an array of

Unicode characters that comprise it.• ReleaseStringChars– Releases the pointer to the array of Unicode characters

• NewString– Constructs a new String object from an array of Unicode

Characters• GetStringLength– Returns the length of a string of Unicode characters

Page 22: Java Native Interface (JNI)

Java arrays

• Note that you can NOT do the following: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]; /* NO! – why not? } ...• Must use java methods to access array data in C

Page 23: Java Native Interface (JNI)

Array methods

• The previous example should be written as:jsize len = (*env)->GetArrayLength(env,arr);jint *body = (*env)->GetIntArrayElements(env,arr,0);for (i=0;i<len;++i){ sum += body[i]; }(*env)->ReleastIntArrayElements(env,arr,body,0);/* very important – copies back to java array if copy had to be

made */

Page 24: Java Native Interface (JNI)

Array methods, cont.

• Note that there are analagous functions for float, byte, double, etc:– Get<type>ArrayElements– Release<type>ArrayElements

• Important: These Get functions may copy the entire array. If this is undesirable, use

Get/Set<type>ArrayRegion functions

Page 25: Java Native Interface (JNI)

Function for accessing arrays

Function Array TypeGetBooleanArrayElements booleanGetByteArrayElements byteGetShortArrayElements shortGetIntArrayElements intGetLongArrayElements longGetFloatArrayElements floatGetDoubleArrayElements doubleGetObjectArrayElements object

Page 26: Java Native Interface (JNI)

Functions for releasing arraysFunction Array Type

ReleaseBooleanArrayElements booleanReleaseByteArrayElements byteReleaseShortArrayElements shortRelaseIntArrayElements intReleaseLongArrayElements longReleaseFloatArrayElements floatReleaseDoubleArrayElements doubleReleaseObjectArrayElements object

Page 27: Java Native Interface (JNI)

Calling java methods

• What if you pass a java object to a C routine and wish to “call back” a method on the Java object.

• Good to avoid this when you can but sometimes it is very important.

• Need to use the jobject reference that is passed in by java.

Page 28: Java Native Interface (JNI)

Steps to follow

• Native method calls JNI function GetObjectClass– returns the jclass object that is type of that obj

• Native method calls JNI function GetMethodID– returns jmethodID of method in class (0 for no such method)

• Finally, native method calls JNI function CallVoidMethod.– invokes an instance of method with void return type. You pass

object, methodID, and actual arguments.

Page 29: Java Native Interface (JNI)

A simple alternative – spawning a system executable

• Advantages – Infinitely simpler– Portable– Can use any native language

• Disadvantages– Can only pass data to and from vi stdout– Must reload executable for each invocation

Page 30: Java Native Interface (JNI)

Spawning Executable -- technique

• Process p = Runtime.exec(“some_exec”);• Use p to manage process:– p.getInputStream();– p.getOutputStream();– p.kill();– p.halt();

Page 31: Java Native Interface (JNI)

Legacy Collections

• java.util.Vector– Still useable, but typically ArrayList is preffered.– Only major difference is if you are using muliple

threads• java.util.HashTable– Still useable, but typically HashMap is preferred.– Again, different if using multiple threads.