// Простой пример, который использует native-метод.
public class NativeDemo {
int i;
public static void main(String args[]) {
NativeDemo ob = new NativeDemo();
ob.i = 10;
System.out.println("Этот ob.i перед native-методом:" + ob.i);
ob.test(); // Вызов native-метода
System.out.println("Этот ob.i после native-метода:" + ob.i);
}
// Объявить native-метод
public native void test();
// Загрузить DLL, который содержит static-метод
static {
System.loadLibrary("NativeDemo");
}
}
Заметим, что метод test() объявлен как native и не имеет тела. Он будет реализован на С. Обратите также внимание на блок static. Как объяснялось ранее, static-блок выполняется только один раз, когда программа начинает выполняться (или, более точно, когда его класс впервые загружается). В данном случае он используется для загрузки DLL-библиотеки (Dynamic Link Library — библиотека программ с динамической загрузкой.), которая содержит native-реализацию метода test(). (Далее вы увидите, как можно создать такую библиотеку.)
Библиотека загружается методом loadLibrary(), который является частью класса system. Вот его общая форма:
static void loadLibrary (String filename)
Здесь filename— строка, которая специфицирует имя файла, содержащего библиотеку. Для среды Windows 95/98/NT предполагается, что этот файл имеет расширение .dll.
После ввода программы, откомпилируйте ее, чтобы получить файл NativeDemo.class. Затем, вы должны использовать JDK-утилиту javah.exe для получения файла C/C++ заголовка NativeDemo.h. Файл NativeDemo.h нужно включить в реализацию метода test(). Для построения NativeDemo.h используйте следующую команду:
javah -jni NativeDemo
Данная команда производит файл заголовка с именем NativeDemo.h. Этот файл должен быть включен в С-файл, который реализует test(). Вывод указанной команды:
/* НЕ РЕДАКТИРУЙ ЭТОТ ФАЙЛ - он сгенерирован машиной */
#include <jni.h>
/* Заголовок класса NativeDemo */
#ifndef _Included_NativeDemo
#define _Included_NativeDemo
#ifdef __cplusplus
extern "C" {
#endif /*
* Class: NativeDemo
* Method: test
* Signature: ()V
*/
JNIEXPORT void JNI CALL Java_NativeDemo_test
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Обратите особое внимание на следующую строку, определяющую прототип функции test(), которую вы будете создавать:
Заметим, что имя функции — Java_NativeDemo_test() - его нужно использовать как имя native-функции, которую вы реализуете. То есть вместо создания С-функции, названной test(), вы будете создавать функцию с именем Java_NativeDemo_test(). Компонент NativeDemo префикса добавляется потому, что он идентифицирует метод test() как часть класса NativeDemo. Помните, что другой класс может определить свой собственный native-метод test(), который полностью отличается от того, что объявлен в NativeDemo.
Включение в префикс имени класса обеспечивает возможность дифференцировать различные версии. Общее правило: native-функциям нужно давать имя, чей префикс включает имя класса, в котором они объявлены.
После создания необходимого файла заголовка вы можете написать свою реализацию test() и сохранить его в файле с именем NativeDemo.с:
Заметим, что файл включает jni.h, который содержит интерфейсную информацию. Этот файл обеспечивается Java-компилятором. Файл заголовка NativeDemo.h был создан ранее с помощью утилиты javah.
В этой функции метод Getobjectciass() используется для получения С-структуры, которая содержит информацию о классе NativeDemo. Метод GetFieldlD() возвращает С-структуру с информацией о поле класса с именем ”i”. Метод GetIntFieid() извлекает первоначальное значение этого поля. Метод SetIntField() хранит обновленное значение в данном поле. (Дополнительные методы, которые обрабатывают другие типы данных, см. в файле jni.h.)
После создания NativeDemo.c нужно откомпилировать его и создать DLL-файл. Для этого используется Microsoft-компилятор C/C++ со следующей командной строкой:
Cl /LD NativeDemo.c
Это создает файл с именем NativeDemo.dll. Как только указанная процедура проделана, можно выполнять Java-программу, которая сгенерирует следующий вывод:
Этот ob.i перед native-методом: 10
Запуск native-метода, i = 10
Завершение native-метода.
Этот ob.i после native-метода: 20
Специфика использования native зависит от реализации и среды. Кроме того, специфика способа взаимодействия с кодом Java подвергается изменениям. По деталям работы с native-методами нужно обращаться к документации системы разработки Java-программ.