Перевод не даст общей идеи, которая заключается в том, что из JVM можно запустить код, который написан на какой-либо компилируемом языке (например на C) и лежит на диске в виде .dll ( для Unix это обычно .so )
JNI был придуман и реализован для тех, кто нуждается в вызовах, которые JAVA сделать не может совсем – это какие-нибудь машино-зависимые команды или обращения к API операционной системы, обращение к драйверам и прочая.
Достаточно полное описание можно найти здесь: Java Native Interface
А ниже сделан очень простой вариант использования JNI. Пример сделан для того, чтобы увидеть насколько несложно использовать этот механизм.
Итак, что надо:
1. Создаем обычный класс на JAVA, но тот метод, который должен использовать dll описываем как native. Кроме этого используем вызов, который загружает нашу dll.
1 2 3 4 5 6 7 8 9 10 |
public class JniTest { static { System.loadLibrary("JniTest"); } // обращаем внимание на слово native public native int showString(String message); } |
Теперь компилируем наш пример
1 |
javac JniTest.java |
Если ничего страшного не произошло, то по идее мы должны получить файл JniTest.class.
Теперь обработаем его утилитой javah. Эта утилита создаст нам .h файл для нашей программы.
Важно: надо писать файл без расширения.
javah -classpath . JniTest
Получаем файл JniTest.h вот такого вида.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class JniTest */ #ifndef _Included_JniTest #define _Included_JniTest #ifdef __cplusplus extern "C" { #endif /* * Class: JniTest * Method: showString * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_JniTest_showString (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif |
Редактировать его уже не надо. Его надо просто включить в наш файл CPP (JniTest.cpp), который показан ниже.
1 2 3 4 5 6 7 8 9 10 11 |
#include #include "JniTest.h" JNIEXPORT jint JNICALL Java_JniTest_showString(JNIEnv * jenv, jobject jobj, jstring message) { const char *string = jenv->GetStringUTFChars(message, 0); printf("%s\n",string); jenv->ReleaseStringUTFChars(message, string); return 0; } |
В нем следует обратить внимание на обработку строк. Остальные переменные обычно не так сложны. А тут видим, что надо вытащить строку из Unicode в обычный char.
Теперь сделаем dll для нашего проекта. Лучше было бы, чтобы в системе уже был прописан путь до компилятора.
JAVA_HOME — это переменная среды, которую я всегда прописываю. Вообще это путь до директории с установленной JAVA — например, C:\j2sdk15. (Думаю, что это понятно)
cl -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -LD JniTest.cpp -FeJniTest.dll
cl — это компилятро С++ из Visual C++. Вы можете использовать любой другой компилятор. Тут важно собрать наши исходники на Си для получения DLL.
Видно, что результатом компиляции должна быть JniTest.dll. Кстати, для Unix-систем должен быть файл вида libJniTest.so. Вот такая особенность. Нужен префикс lib.
Теперь создаем тестовый пример.
1 2 3 4 5 6 7 8 9 |
public class ShowJniTest { public static void main(String[] args) { JniTest jt = new JniTest(); jt.showString("Hello, world!"); jt.showString("JNI is great!"); } } |
Собираем
javac -classpath . ShowJniTest.java
И запускаем
java -classpath . ShowJniTest
Должно сработать.