Использование JNI в Delphi
Приветствую всех. Эта статья рассчитана для Новичков, которые только приступили к изучению JNI для работы с ним в среде Delphi. И так в этой статье мы поговорим как именно использовать JNI в Delphi. И так давайте же приступим.
Для начала вам потребуется компонент JNI. Вы можете его скачать ТУТ. Теперь мы готовы приступить к практической части. Я все буду делать на RAD Studio 10.1 Berlin
Пример №1:
Получаем и изменяем данные типа JInt, JBoolean.
Допустим что у нас есть Класс в котором есть переменная I типа JInt, следовательно нам нужно ее изменить.
public int I = 10;
И есть некий обработчик который использует эту переменную. К примеру Событие нажиния TButton.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
System.out.println(i);
}
При нажатии на Кнопку в консоль выведется сообщение «10» т.к. I = 10; Чтобы нам изменить I на любое другое число, делаем следующее:
var
JNIEnv: PJNIEnv;
JC: JClass;
JF: JFieldID;
Begin
JC:= jnienv^.FindClass(JNIEnv, 'example/Main');
JF:= jnienv^.GetFieldID(JNIEnv, JC, 'I', 'I');
jnienv^.SetIntField(JNIEnv, JC, JF, 5);
end;
Что же тут происходит. Для начала мы получаем JavaClass функцией FindClass. 'example/Main' это значит что класс находится внутри JVM по пути exampleMain.class.
Далее мы получаем JField в данном случае это I типа JInt. GetFieldID мы указываем Класс, Имя и Сигнатуру.
И наконец мы передаем свое значение I, в моем случаем оно равно 5. SetIntField мы указываем Класс, JField и значение.
То же самое будет для JBoolean:
public boolean Stat = false;
var
JNIEnv: PJNIEnv;
JC: JClass;
JF: JFieldID;
Begin
JC:= jnienv^.FindClass(JNIEnv, 'example/Main');
JF:= jnienv^.GetFieldID(JNIEnv, JC, 'Stat', 'Z');
jnienv^.SetByteField(JNIEnv, JC, JF, 1);
end;
Изначально Stat был равен false т.е. 0, а мы его меняем на true т.е. 1;
Пример №2:
Обращение к процедуре Void()
Допустим у нас есть некая статичная процедура в которой выполняется некий сценарий. Процедура будет выполняться при нажатии на кнопку. Для того чтобы выполнить эту процедуру будем делать обращение к Методу.
public static void Push()
{
System.out.println("Hello");
}
Как мы видим эта процедура будет просто выводить в Консоль «Hello». Чтобы вызвать исполнение этой процедуры делаем следующее:
var
JNIEnv: PJNIEnv;
JC: JClass;
JM: JMethodID;
Begin
JC:= jnienv^.FindClass(JNIEnv, 'example/Main');
JM:=jnienv^.GetStaticMethodID(JNIEnv, JC, 'Push', '()V');
jnienv^.CallStaticVoidMethod(JNIEnv, JC, JM);
end;
Что же тут происходит. Мы получаем Статический Метод Push. GetStaticMethodID где мы указали Класс, Имя и Сигнатуру.
И вызываем его на исполнение CallStaticVoidMethod где мы указали Класс и Метод.
Пример №3
Обращение к функции с переменной JInt.
Допустим у нас есть некая функция у которой есть переменная I типа JInt. И результат выполнения является JInt, а некий сценарий внутри функции выдает в Консоль некие сообщения
public static int Num(int i)
{
for (int s=0; s<i; s++) {
System.out.println("Example");
}
return i;
}
По сути в консоль будет выдаваться I количество сообщений «Example». Давай рассмотрим обращение к такой функции.
var
JNIEnv: PJNIEnv;
JC: JClass;
JM: JMethodID;
Begin
JC:= jnienv^.FindClass(JNIEnv, 'example/Main');
JM:=jnienv^.GetStaticMethodID(JNIEnv, JC, 'Num', '(I)I');
jnienv^.CallStaticVoidMethodV(JNIEnv, JC, JM, '5');
end;
Что же тут происходит. Мы находим Нужный Метод. И производим вызов его, но в этот с указанием JInt. В данном случае это 5.
И так результат выполнения этой функции будет вывод в Консоль 5 раз сообщений «Example»
Автор: Жрец