新しい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への接続とその中の特定のプロシージャの実行を取得します。