170 likes | 324 Views
Native Methods. Why Use Native Methods?. While a pure Java solution is nice in principle for an application, there are situations where we want to write (or use) code written in another programming language. Such code is usually called native code.
E N D
Why Use Native Methods? • While a pure Java solution is nice in principle for an application, there are situations where we want to write (or use) code written in another programming language. • Such code is usually called native code. • There are three reasons why this may be the right choice: 1. We have substantial amounts of tested and debugged code available in that programming language. Porting the code to Java would be time consuming, and the resulting code would need to be tested and debugged again.
Why Use Native Methods? 2. Our application requires access to system features or devices, and using Java technology would be cumbersome or impossible. 3. Maximizing the speed of the code is essential. For example, the task may be time-critical, or it may be code that is used so often that optimizing it has a big payoff. This third reason is not very plausible, since with just-in-time (JIT) compilation, intensive computa- tions coded in Java are not that much slower than compiled C code.
Why Use Native Methods? • If we are in one of these three situations, it might make sense to call the native code from Java programs. • Note that if we use native methods, we lose portability. • Native libraries are not as safe as Jave code, especially if they are written in a language like C or C++ that offers no protection against overwriting memory through invalid pointer usage. • Don't use native code if you don't really need it. Use native code only as a last resort.
Java Native Interface (JNI) • To make calling native methods possible, Java technology comes with libraries and software tools to relieve some (but not all) of the programming tasks. • We use C as our language for native methods because C is the language most often used for native codes. • We will learn the so-called Java Native Interface (JNI) binding.
Calling a C Function from Java Programs • We have to give the run time system enough information so that it can link a native method call to the right implementation of the method. • This requires a three-step process: 1. Generate a C stub for a function that translates between the Java method call and the actual C function. The stub does this translation by taking parameter information off the JVM stack and passing it to the compiled C function. 2. Create a special shared library and export the stub from it. 3. Use a special method, such as System.load, to tell the Java runtime environment to load the library from Step 2.
Calling a C Function from Java Programs • First we need to declare the native method in a class. • The native keyword tells the compiler that the method is defined externally. • The method header is followed immediately by a terminating semicolon. This means that native method declarations look similar to abstract method declarations. • Native methods can be static or nonstatic.
HelloNative.java class HelloNative { public static native void greeting(); static { System.load( "/tmp/advprog2004/native/libHelloNative.so"); } } • Compile this program to obtain HelloNative.class with javac.
Next, we write a corresponding C function. This function must be named exactly the way the Java runtime environment expects. • The javah utility can be used to generate the function name automatically. • The execution of the command: javah HelloNative produces a C header file, HelloNative.h.
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloNative */ #ifndef _Included_HelloNative #define _Included_HelloNative #ifdef __cplusplus extern "C" { #endif /* * Class: HelloNative * Method: greeting * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloNative_greeting (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif HelloNative.h
HelloNative.c #include "HelloNative.h" #include <stdio.h> JNIEXPORT void JNICALL Java_HelloNative_greeting (JNIEnv *env, jclass cl) { printf("Hello native world!\n"); }
Next, the C code is compiled into a dynamically loaded library: gcc -c -fPIC -I/usr/local/j2sdk1.4.2/include -I/usr/local/j2sdk1.4.2/include/linux HelloNative.c gcc -shared -o libHelloNative.so HelloNative.o • Now, the application HelloNativeTest can be run.
HelloNativeTest.java class HelloNativeTest { public static void main( String[] args ) { HelloNative.greeting(); } }
Example using the function printf() • Printf1.java • Printf1Test.java • Printf1.c • Printf1.h