Всем доброго времени суток! Сегодня разберем пример как получить загруженную JVM и подключиться к ней. Нужно нам это для того, чтобы выполнить внутри JVM некий код.Итак, приступим:
Создаем новый проект DLL. Добавим Process Attach:
Отлично, добавили. Далее нас потребуется в Uses добавить компонент JNI:
А теперь давайте реализуем поиск и подключение к JVM. Для этого в DllMain добавим переменные:
Далее в
Что же тут происходит. Для начала нам нужно получить адрес функции
Итак мы нашли и подключились к загруженной JVM. Теперь можно использовать любой код внутри JVM после строчки
Давайте приведем пример как это использовать. Допустим, у вас есть некая функция, которую вы хотите использовать в Java.
Это простое обращение к Методу в JNI и чтоб его использовать достаточно поместить эту процедуру после
В итоге мы получаем подключение к JVM и выполнение в ней некой процедуры.
Создаем новый проект DLL. Добавим Process Attach:
procedure DllMain(dwReason: LongWord); begin case dwReason of DLL_PROCESS_ATTACH: begin //************************** end; DLL_PROCESS_DETACH: begin //*************************** end; end; end; begin DllProc := @DllMain; DllProc(DLL_PROCESS_ATTACH); end.
Отлично, добавили. Далее нас потребуется в Uses добавить компонент JNI:
uses System.SysUtils, System.Classes, windows, JNI;
А теперь давайте реализуем поиск и подключение к JVM. Для этого в DllMain добавим переменные:
var I: Integer; JVMArray: array of PJavaVM; NumberOfVMs: JSize; JNIEnv: PJNIEnv; GetCreatedJavaVMs: TJNI_GetCreatedJavaVMs; const BufferSize = 128;
Далее в
DLL_PROCESS_ATTACH реализуем поиск и подключение загруженной JVMbegin try GetCreatedJavaVMs := GetProcAddress(GetModuleHandle('jvm.dll'), 'JNI_GetCreatedJavaVMs'); SetLength(JVMArray, BufferSize); GetCreatedJavaVMs(@JVMArray[0], BufferSize, @NumberOfVMs); except Exit; end; if NumberOfVMs > 0 then begin for I := 0 to NumberOfVMs - 1 do begin JVMArray[I]^.GetEnv(JVMArray[I], @JNIEnv, JNI_VERSION_1_8); JVMArray[I]^.AttachCurrentThread(JVMArray[I], @JNIEnv, Nil); end; end else begin Exit; end;
Что же тут происходит. Для начала нам нужно получить адрес функции
JNI_GetCreatedJavaVMs из jvm.dll. Затем установим длину буфера. Затем используем функцию GetCreatedJavaVMs для получения всех загруженных JVM. Ну а дальше просто отсев в буфере пока не останется именно та загруженная JVM и подключаемся к ней AttachCurrentThread.Итак мы нашли и подключились к загруженной JVM. Теперь можно использовать любой код внутри JVM после строчки
AttachCurrentThread. И в итоге мы получаем код DLL:library Project1; uses System.SysUtils, System.Classes, windows, JNI; procedure DllMain(dwReason: LongWord); var I: Integer; JVMArray: array of PJavaVM; NumberOfVMs: JSize; JNIEnv: PJNIEnv; GetCreatedJavaVMs: TJNI_GetCreatedJavaVMs; const BufferSize = 256; begin case dwReason of DLL_PROCESS_ATTACH: begin try GetCreatedJavaVMs := GetProcAddress(GetModuleHandle('jvm.dll'), 'JNI_GetCreatedJavaVMs'); SetLength(JVMArray, BufferSize); GetCreatedJavaVMs(@JVMArray[0], BufferSize, @NumberOfVMs); except Exit; end; if NumberOfVMs > 0 then begin for I := 0 to NumberOfVMs - 1 do begin JVMArray[I]^.GetEnv(JVMArray[I], @JNIEnv, JNI_VERSION_1_8); JVMArray[I]^.AttachCurrentThread(JVMArray[I], @JNIEnv, Nil); end; end else begin Exit; end; end; DLL_PROCESS_DETACH: begin Exit; end; end; end; begin DllProc := @DllMain; DllProc(DLL_PROCESS_ATTACH); end.
Давайте приведем пример как это использовать. Допустим, у вас есть некая функция, которую вы хотите использовать в Java.
procedure Com(JNIEnv: PJNIEnv); var JC: JClass; JM: JMethodID; Begin JC:=jnienv^.FindClass(JNIEnv, 'ru/er_log/components/Frame'); JM:=jnienv^.GetMethodID(jnienv, jc, 'login', 'Ljavax/swing/JTextField;'); jnienv^.CallObjectMethod(jnienv, jc, jm); End;
Это простое обращение к Методу в JNI и чтоб его использовать достаточно поместить эту процедуру после
AttachCurrentThread.begin JVMArray[I]^.GetEnv(JVMArray[I], @JNIEnv, JNI_VERSION_1_8); JVMArray[I]^.AttachCurrentThread(JVMArray[I], @JNIEnv, Nil); Com(JNIEnv); end;
В итоге мы получаем подключение к JVM и выполнение в ней некой процедуры.
