Всем доброго времени суток!
Сегодня разберем пример как получить загруженную JVM и подключиться к ней. Нужно нам это для того что выполнить внутри 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: реализуем поиск и подключение загруженной JVM
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;
Что же тут происходит. Для начала нам нужно получить адрес функции JNI_GetCreatedJavaVMs из jvm.dll. Затем установим длину буфера. Затем используем функцию GetCreatedJavaVMs для получения всех загруженных JVM. Ну а дальше просто отсев в буфере пока не останется именно та загруженная JVM и подключаемся к ней AttachCurrentThread.
И так мы нашли и подключились к загруженной JVM. Теперь можно использовать любой код внутри JVM после строчки AttachCurrentThread.
ссылка на оригинал статьи https://habrahabr.ru/post/324594/
Добавить комментарий