JNI DelphiでのJVMの取得と接続

すべての人に良い一日を! 今日は、ロードされたJVMを取得して接続する方法の例を分析します。 JVM内でコードを実行するためにこれが必要です。



新しいDLLプロジェクトを作成します。 プロセス接続を追加します。



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.
      
      





素晴らしい、追加しました。 次に、JNIコンポーネントをUsesに追加する必要があります。



 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の検索と接続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;
      
      





ここで何が起こっていますか。 まず、jvm.dllからJNI_GetCreatedJavaVMs



関数のアドレスを取得する必要があります。 次に、バッファーの長さを設定します。 次に、 GetCreatedJavaVMs



関数を使用して、ロードされたすべてのJVMを取得します。 さて、ロードされたJVMが残るまでAttachCurrentThread.



をバッファーにドロップするだけAttachCurrentThread.







そこで、ロードされたJVMを見つけて接続しました。 これで、 AttachCurrentThread



行の後にJVM内の任意のコードを使用できます。 そして最後に、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のMethodの単純な呼び出しであり、使用するには、このプロシージャをAttachCurrentThread



後にAttachCurrentThread



ます。



  begin JVMArray[I]^.GetEnv(JVMArray[I], @JNIEnv, JNI_VERSION_1_8); JVMArray[I]^.AttachCurrentThread(JVMArray[I], @JNIEnv, Nil); Com(JNIEnv); end;
      
      





その結果、JVMへの接続とその中の特定のプロシージャの実行を取得します。



All Articles