JNI и Delphi. Использование Java методов при помощи JNI

—

от автора

Всем доброго времени суток!

Сегодня мы рассмотрим такую тему, как использовать Java методы при помощи JNI.
На самом деле все очень просто. Давайте сразу начнем с примера:

Допустим у нас есть некое Java приложение на котором есть простая кнопка и при нажатии на эту кнопку будет исполняться некий код.

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                                  File MyFile = new File("D:\\Sample\\text.txt");         MyFile.delete();     }                        

Как мы видим в событии клика на кнопку будет исполняться просто код для удаления файла.
На Java все выглядит ясно и просто, но как же это будет выглядеть на Delphi с использованием JNI. На самом деле все проще чем кажется.
Для этого нам нужно разобрать заглянуть и в класс File, который находится по адресу java.io.File. Из этого класса нам нужно:

— Получиться сам класс
— Получить функцию delete, а именно Имя и Дескриптор.
— Заполнить аргумент для данной функции
— Использовать ее.

И так приступим.
Самой удобной утилитой для разборки класса на чечки на мой взгляд является DirtyJOE. КИдаем туда класс File и в методах ищем нашу функцию. Находим ее Имя и Дескриптор. Переходим в Delphi и создаем там такую функцию.

function JVM_DeleteFile(JNIEnv: PJNIenv; FilePath: String): Boolean;

Обратим внимание в DirtyJOE что функция delete возвращает назад Boolean.
Тут все просто: Название функции и объявляем переменные.
Давайте объявим переменные для работы нашего кода:

var   FileClass: JClass;   Delete, Init: JMethodID;   FileObj: JObject;   Args: array[0..0] of JValue;

Это все то что далее мы будем искать и использовать.
Теперь давайте заполним Аргументы

Args[0].l:= WideToJString(jnienv, PwideChar(WideString(FilePath)));

Обратите внимание что JString мы передаем как JObject (По сути JString это и есть JObject)
Ну а далее мы будем получать класс и метод delete:

FileClass:= jnienv^.FindClass(jnienv, 'java/io/File');   Delete:= jnienv^.GetMethodID(jnienv, FileClass, 'delete', '()Z');

А теперь не мало важный этап. Обратите внимание что в Java коде мы создаем новый объект new File и в Delphi нам требуется сделать тоже самое:

Init:= jnienv^.GetMethodID(jnienv, FileClass, '<init>', '(Ljava/lang/String;)V');   FileObj:= jnienv^.NewObjectA(jnienv, FileClass, Init, @Args);

И нам по сути осталось только использовать сам метод delete:

jnienv^.CallBooleanMethod(jnienv, FileObj, Delete)

Но, так как вначе всего мы обратили внимание что функция delete возвращает Boolean, то давайте же сделаем проверку на возврат True и False:

if jnienv^.CallBooleanMethod(jnienv, FileObj, Delete) = 1 then   Result:= True   else   Result:= False;

Ну и давайте посмотрим на эту функцию в готовом виде:

function JVM_DeleteFile(JNIEnv: PJNIenv; FilePath: String): Boolean; var   FileClass: JClass;   Delete, Init: JMethodID;   FileObj: JObject;   Args: array[0..0] of JValue; begin   Args[0].l:= WideToJString(jnienv, PwideChar(WideString(FilePath)));   FileClass:= jnienv^.FindClass(jnienv, 'java/io/File');   Delete:= jnienv^.GetMethodID(jnienv, FileClass, 'delete', '()Z');   Init:= jnienv^.GetMethodID(jnienv, FileClass, '<init>', '(Ljava/lang/String;)V');   FileObj:= jnienv^.NewObjectA(jnienv, FileClass, Init, @Args);   if jnienv^.CallBooleanMethod(jnienv, FileObj, Delete) = 1 then   Result:= True   else   Result:= False; end;

Заключение.
На самом деле все проще чем кажется. С помощью JNI можно использовать любой Java метод. В этом примере, если вы внимательно смотрели то увидели что я использовал запись Аргументов типа JValue и как нужно их использовать. Это очень важный момент.

ссылка на оригинал статьи https://habr.com/ru/post/515234/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *