通過 JNI 讓 JAVA 與 Delphi 程序交互(四)
在上一篇中,我們說了如何用 Java 調用 Delphi 程序的一個方法并傳遞給其一個參數
現在我們再來看一下如果如果要調用的方法有返回值,又要怎么做.
首先,我們先定義如下的 Java 類:
//------------------------------------------------------------------------------
package alvinJNI;
class HelloWorld {
??????? static {
??????????????? System.loadLibrary("DelphiAction");
??????? }
??????? public native String printText(String arg);
??????? public static void main(String[] args) {
??????????????? HelloWorld hw = new HelloWorld();
??????????????? System.out.println(hw.printText("你好"));
??????? }
}
//-------------------------------------------------------------------------------
我們再像上次一樣在 Delphi 中建立 DLL 工程,寫下面的代碼(有注釋):
//-------------------------------------------------------------------------------
library DelphiAction;
uses
? JNI;
//今天,因為這個方法有返回值,所以不再是 procedure 過程,我們要變成 function 函數, 返回值類型為 JString
function Java_alvinJNI_HelloWorld_printText(PEnv: PJNIEnv; Obj: JObject; arg: JString): JString; stdcall;
var
? tmpStr: String;
? JVM: TJNIEnv;
? tt: Boolean;
begin
? JVM:= TJNIEnv.Create(PEnv);
? //我們這里先把參數提交過來的 JString 轉換成 Delphi 中的 String 后就可以使用了
? tmpStr := '你想輸出的字符串是: "' + JVM.UnicodeJStringToString(arg) + '"。';
? //當字符串要轉換成 JString 我們需要先對字符串進行 UTF8 編碼后再轉換成 PChar 再轉換成 JString
? //這樣才能保證返回的字符串在 JAVA 中不亂碼
? Result := JVM.StringToJString(pchar(UTF8Encode(tmpStr)));
? JVM.Free;
end;
exports
??????? Java_alvinJNI_HelloWorld_printText;
end.
//--------------------------------------------------------------------------------
再看看效果吧,是不是成功了?
這里如果返回值的類型是其它的其本類型,比如 JLong,JInt,JFloat,JDouble,JBoolean,JShort,JByte
這些類型的數據可以直接與 Delphi 中的數據運算,對應 Int64,Integer,Single,Double,Boolean,SmallInt,ShortInt
返回時可以直接給 Result 賦 Delphi 中的數值. 如:
function Java_alvinJNI_HelloWorld_getInt(PEnv: PJNIEnv; Obj: JObject): JInt; stdcall;
var
? tmp: Integer;
begin
? tmp := 10;
? Result := tmp;
end;
如果返回值的類型是 Object 的 Java 對象,返回 JObject 類型,它的用法我們在以后再來學習.
如果返回值的類型是 Type[] 數組,接收參數時要設為 JObject 類型,怎樣創建這樣的數組對象,我自己也還不知道,以后知道了我再來貼上
因為 Java 是把數組作為對象看待的.它要以以下的方式來使用:
例如: 我們要給 Delphi 的方法傳入一個 byte[] 型數組,在定義 Delphi 方法時參數聲明為 bytearray: JObject
在方法中:
var
?PByteArr: PJByte?? //PJByte 是 JNI.pas 定義的, 里面還有 PJBoolean, PJObject, PJInt 等..
?JVM: TJNIEnv;
?isCopy: Boolean;
begin
?JVM:= TJNIEnv.Create(PEnv);
?isCopy := false;
?PByteArr := JVM.GetByteArrayElements(bytearray, isCopy);? //調用這個方法,可以將取得參數 bytearray 的地址, isCopy 決定是否復制數組
?//之后,我們可以通過 PByteArr 結合 inc(PByteArr) 這個指針來操作傳過來的數組.
end;
好了,就先說到這里,今天,你是不是又學到了什么?