jni - call C/C++/Assembly from Java
Friday, May 23, 2008
- Create Java class containing native method(s) (static or instance) defining interface with C code.public class Processor {
public static native double process(double x, double y);
} - Compile to Java class file.
- Run javah -jni [-o path/to/CProcessor.h] Processorto generate C header file from the Java. Eg. CProcessor.h:/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Processor */
#ifndef _Included_Processor
#define _Included_Processor
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Processor
* Method: process
* Signature: (DD)D
*/
JNIEXPORT jdouble JNICALL Java_Processor_process
(JNIEnv *, jclass, jdouble, jdouble);
#ifdef __cplusplus
}
#endif
#endif - Create a .c C source file - this is the stub to call the target code. Include header
and "Processor.h". The angle brackets mean it is registered as a library file for the compiler, whereas the speech marks denote a stand-alone header file. May need to include the path the Processor.h within the speech marks. Here is a simple example that just sums the two input numbers, rather than calling any other C: #include <jni.h>
#include <math.h>
#include "../headers/CProcessor.h"
#include <stdio.h>
JNIEXPORT jdouble JNICALL Java_Processor_process
(JNIEnv *env , jclass obj, jdouble val1, jdouble val2) {
return (val1+val2);
} - Run (eg for linux)gcc -shared -I /usr/lib/jvm/java-1.5.0-sun-1.5.0.15/include/ -Ito create the library file (indicated by 'shared' flag). Any compiler errors about missing .h headers should be solved by the inclusion (-I) of the jni and jni for linux paths.
/usr/lib/jvm/java-1.5.0-sun-1.5.0.15/include/linux/ -o CProcessor.so CProcessor.c - Either in a method inside original Java class, or in a new calling class, create a static block to either load (System.load()) the .so library via its file path, or load (System.loadLibrary()) a registered library (e.g. dll on Windows) via system-specific addressing.
- Once the static block has loaded the library, the methods are available either statically or from an object as determined in 1.public class Caller {In this case our Processor in Java calls the CProcessor in C which adds the 2 doubles we passed it and returns a double. Here it is 2 + 3 with the output 5.
static {
System.load("/home/me/_projects/JNI/C/CProcessor.so");
}
public static void main(String[] args) {
double result = Processor.process(2, 3);
System.out.println(result);
}
}
0 comments:
Subscribe to:
Post Comments (Atom)