转:Java JNI 和 Delphi 相互調用(2)-Delphi調用Java

前幾天寫了  Java JNI 和 Delphi 相互調用(1)-JAVA調用DELPHI ,有朋友要求儘快寫“Delphi調用Java”,現在有空,就寫下去。

DELPHI 調用 JAVA 的方法,作為入門也不算複雜,只是創建JVM的環境麻煩一些。進行的順序是:

a.建立 JVM 環境
b.創建 JAVA 環境實例
c.找到 class
d.找到方法
e.調用方法
f.結束

如何得到 DELPHI 的 JNI 定義,請看前一篇中的說明。直接進入主題。

二、介紹 DELPHI 調用 JAVA 的方法
1、創建一個 DelphiCallJava.java,文件的內容:
public class DelphiCallJava {

    public static String dTest(String args){
        if(args==null){
            return "您沒有輸入參數.";
        }else {
            return "您輸入的參數是:"+args;
        }
    }
}


這個類太簡單了,沒什麼可說的。將這個 class 保存成無 BOM 的 UTF-8 格式文件。同樣,從簡單起見,也是沒有創建包的。再用下面這個命令行進行編譯:
javac -encoding utf-8 DelphiCallJava.java


2、創建 Delphi 的EXE工程
JAVA 的數據類型轉換到 DELPHI 的數據類型,請看 jni.pas 中的定義。

DelphiCallJava.dpr 的代碼:


program DelphiCallJava;
{$APPTYPE CONSOLE}

uses Windows, SysUtils, Variants, Classes, jni;

const Handle=0;
const strParam='傳給java的參數';

label lexit;
var    jvm: Jni.PJavaVM;
    tenv: Jni.TJNIEnv;

    cid: Jni.JClass;
    mid: Jni.JMethodID;
    tmp: Jni.JString;
    
    vm_args: Jni.JavaVMInitArgs;                       //建立 JVM 的參數
    options: array[0..2] of Jni.JavaVMOption;
    env: Jni.PJNIEnv;
    rec: Integer;
begin
    options[0].optionString := '-Djava.compiler=NONE';
    options[1].optionString := '-Djava.class.path=.';   // Java 工程路徑, '.' 表示黨前路徑
    options[2].optionString := '-verbose:jni';

    JNI_GetDefaultJavaVMInitArgs(@vm_args);
    vm_args.version := Jni.JNI_VERSION_1_4;
    vm_args.options := @options;
    vm_args.nOptions := 3;
    vm_args.ignoreUnrecognized := Jni.JNI_TRUE;

    rec := Jni.JNI_CreateJavaVM(@jvm, @env, @vm_args);   //建立JVM
    if (rec = JNI_ERR ) then begin
        Windows.MessageBox(Handle, 'create JVM exception.', ’DelphiCallJava‘, Windows.MB_OK);
        exit;
    end;
    
    tenv := TJNIEnv.Create(env);
    if tenv=nil then Begin
        Windows.MessageBox(Handle, 'Please load jvm first.', ’DelphiCallJava‘, Windows.MB_OK);
        Exit;
    End;

 

    //取得 DelphiCallJava 的類ID, 如果有'包',也指定, <package>.<class>
    cid := tenv.FindClass('DelphiCallJava');
    if (cid = nil) then begin
        Windows.MessageBox(Handle, '找不到類:DelphiCallJava', ’DelphiCallJava‘, Windows.MB_OK);
        goto lexit;
    end;

    //取得方法ID
    mid := tenv.GetStaticMethodID(cid, 'dTest', '(Ljava/lang/String;)Ljava/lang/String;'); 
    if (tenv.ExceptionOccurred()<>nil) then begin
        Windows.MessageBox(Handle, '找不到方法(dTest)', ’DelphiCallJava‘, Windows.MB_OK);
        goto lexit;
    end;

    //將 string 轉換成 java string
    tmp := tenv.StringToJString(PChar(UTF8Encode(strParam)));
    //用類ID和方法ID調用 JAVA 方法
    tmp := tenv.CallStaticObjectMethod(cid, mid, [tmp]);            
    if (tenv.ExceptionOccurred()<>nil) then begin
        Windows.MessageBox(Handle, '調用方法(dTest)失敗!', ’DelphiCallJava‘, Windows.MB_OK);
        goto lexit;
    end;

    //顯示結果
    writeLn( ''  );
    writeLn( '傳給java的參數是:' +strParam );
    writeLn( 'java返回:'+UTF8Decode(tenv.JStringToString(tmp))  );

    lexit:
    
    if tenv<>nil then begin
        freeAndNil(tenv);
        jvm^.DestroyJavaVM(jvm); //釋放JVM資源
    End;
end.

準備命令行編譯,別忘記 jni.pas 和 jni_md.inc 放在一塊,編譯命令:
dcc32 /B DelphiCallJava.dpr

 

3、執行、測試
將這幾個命令行的編譯做成一個批處理文件:


@ECHO OFF
rem  語言編碼名稱, 要和操作系統相對應,否則會出現亂碼.

rem jre所在的路徑,像 JAVA_HOME 一樣指向安裝的目錄
SET JRE_HOME=C:sdk/jdk1.5.0_15/jre

SET PATH=%PATH%;C:/Program Files/borland/Delphi7/Bin
REM  jvm.dll 一定要在 PATH 所指的路徑下, 因為 Delphi 要調用 jvm.dll
SET PATH=%PATH%;%JRE_HOME%/bin/client


rem java 的編譯命令行
javac -encoding big5 DelphiCallJava.java

REM 編譯delphi的工程
dcc32 /B DelphiCallJava.dpr

rem 執行demo
IF EXIST DelphiCallJava.exe call DelphiCallJava.exe

PAUSE

 ————————————————

版权声明:本文为CSDN博主「cangwu_lee」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cangwu_lee/java/article/details/2242529

posted @ 2020-04-11 11:34  lai1322  阅读(262)  评论(0编辑  收藏  举报