通过 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;
好了,就先说到这里,今天,你是不是又学到了什么?