Java中調(diào)用Delphi編寫(xiě)的DLL
來(lái)源:易賢網(wǎng) 閱讀:860 次 日期:2015-04-10 15:11:53
溫馨提示:易賢網(wǎng)小編為您整理了“Java中調(diào)用Delphi編寫(xiě)的DLL”,方便廣大網(wǎng)友查閱!

有些時(shí)候,要寫(xiě)一些程序,在 JAVA 里面好難實(shí)現(xiàn), 但如果使用其它編程語(yǔ)言卻又比較容易時(shí),我們不妨通過(guò) JNI 來(lái)讓不同語(yǔ)言的程序共同完成.

JNI 的教程, 網(wǎng)上 C 的比較多,Java 也提供了 javah.exe 為 C 語(yǔ)言的 JNI 程序生成頭文件, 如果你是一個(gè) Delphi 編程員, 能否讓 JAVA 與 Delphi 程序交互呢? 答案是肯定的,今天我們就來(lái)看一下一個(gè)簡(jiǎn)單的例子.

Helloworld. 主要是來(lái)認(rèn)識(shí)一下, JAVA 怎樣調(diào)用 Delphi 程序的方法.

好的,我們先來(lái)創(chuàng)建一個(gè)類:

package alvinJNI;

class HelloWorld {

static {

System.loadLibrary("DelphiAction"); //等一下我們就用Delphi來(lái)編一個(gè)程序,編好之后生成的文件就是 DelphiAction.dll 這是一個(gè)動(dòng)態(tài)鏈接庫(kù)文件,這個(gè)類里先在靜態(tài)語(yǔ)句塊中加載它

}

public native void printText(); //聲明一個(gè) native 的本地代碼程序,我們使用的是 Delphi 來(lái)編寫(xiě).注意:這個(gè)方法在這里只是聲明,并沒(méi)有定義方法體,因?yàn)檫@個(gè)方法我們要用 Delphi 來(lái)實(shí)現(xiàn).

public static void main(String[] args) {

//創(chuàng)建對(duì)象并調(diào)用里面的 native 方法.

HelloWorld hw = new HelloWorld();

hw.printText();

}

}

類寫(xiě)完編譯后,接下來(lái)的事情就由 Delphi 來(lái)解決了

我們運(yùn)行 Delphi 后新建 DLL 工程: file->new->other,然后在 new 選項(xiàng)卡里面選擇 Dll Wizard 就創(chuàng)建了一個(gè)新的工程了,

我們選擇一個(gè)文件夾來(lái)保存工程

在保存工程后,我們需要下載 jni.pas 加入到我們的工程中,這是國(guó)外的高手寫(xiě)的程序單元,它方便我們的 Delphi 程序與 JAVA 交互. 可從下面地址下載到:jni_pas.zip

解壓之后里面有兩個(gè)文件,將其存放在工程的目錄下

接下來(lái)我們編寫(xiě) Delphi 代碼:

library DelphiAction; //這里設(shè)置動(dòng)態(tài)鏈接庫(kù)的名稱,因?yàn)槲覀儎偛艑?xiě) JAVA 類時(shí)是用 DelphiAction,所以這里了要設(shè)置為 DelphiAction

{ Important note about DLL memory management: ShareMem must be the

first unit in your library's USES clause AND your project's (select

Project-View Source) USES clause if your DLL exports any procedures or

functions that pass strings as parameters or function results. This

applies to all strings passed to and from your DLL--even those that

are nested in records and classes. ShareMem is the interface unit to

the BORLNDMM.DLL shared memory manager, which must be deployed along

with your DLL. To avoid using BORLNDMM.DLL, pass string information

using PChar or ShortString parameters. 這里面都是注釋,是自動(dòng)生成的,可以刪去 }

Uses

JNI; //注意了,我們剛才下載了 JNI.pas 放在工程目錄中,這里要在 Uses 里面聲明,才能使用.

//下面我們來(lái)寫(xiě)一個(gè)函數(shù),就是為 剛才 JAVA 類實(shí)現(xiàn)一個(gè)簡(jiǎn)單的方法

//因?yàn)橐?JAVA 能夠調(diào)用到這個(gè)函數(shù),所以這個(gè)函數(shù)的命名是非常講究的,名稱各段的分隔符是 _ 下劃線

//本例的函數(shù)如下: 即 Java_包名_類名_類中的方法名

//函數(shù)必須設(shè)置為 stdcall

procedure Java_alvinJNI_HelloWorld_printText(PEnv: PJNIEnv; Obj: JObject); stdcall;

begin

//函數(shù)體非常簡(jiǎn)單,因?yàn)槲覀冎皇橇私庖幌氯绾握{(diào)用 Delphi 的函數(shù).

Writeln('您好!看到效果了吧。');

end;

exports

Java_alvinJNI_HelloWorld_printText; //為函數(shù)做引出聲明,這樣才能真正的被調(diào)用到

end.

代碼完成,我們 Ctrl+F9 編譯 DLL

生成 DelphiAction.dll 后,我們把他復(fù)制到 Java 工程目錄

注意:上面的類是打包在 alvinJNI 包中

假如我們的 Java 工程是在 C:/test

那么剛才編譯后的類必須放在 c:/test/alvinJNI/HelloWorld.class

而剛剛編譯完成的 DelphiAction.dll就放在 c:/test/DelphiAction.dll

然后在 C:/test 目錄中執(zhí)行: java alvinJNI/HelloWorld

看看你的 Java 程序調(diào)用了 DelphiAction 是怎么樣的效果.

呵呵,爽吧! 今天我們才做了一點(diǎn)點(diǎn),只學(xué)了一下如何在 JAVA 調(diào)用 Delphi 和程序,在接下來(lái),我會(huì)貼出更多的教程,以學(xué)習(xí)一些高級(jí)一點(diǎn)點(diǎn)的 JNI 知識(shí).

現(xiàn)在難得來(lái)看一下自己的博客,今天好不容易找了個(gè)代理,順便再繼續(xù)之前的話題,就是 JAVA 與 Delphi 的交互了.

在上一篇中,我們說(shuō)了如何用 Java 調(diào)用 Delphi 程序的一個(gè)方法,今天我們?cè)偕钊胍稽c(diǎn),就是怎樣提交參數(shù)個(gè) Delphi 的方法,以動(dòng)態(tài)的控制 Delphi 的方法.

下面,我們切入正題.

首先,我們定義如下的 Java 類:

//----------------------------------------------------------------------------------------------------------

package alvinJNI;

class HelloWorld {

static {

System.loadLibrary("DelphiAction");

}

public native void printText(String str);

public static void main(String[] args) {

HelloWorld hw = new HelloWorld();

hw.printText("您好!看到效果了吧。");

}

}

//----------------------------------------------------------------------------------------------------------

我們?cè)傧裆洗我粯釉?Delphi 中建立 DLL 工程,寫(xiě)下面的代碼(有注釋):

//----------------------------------------------------------------------------------------------------------

library DelphiAction;

uses

JNI;

//這一次我們要寫(xiě)的這個(gè)方法因?yàn)橐邮找粋€(gè) Java 傳過(guò)來(lái)的參數(shù),所以我們來(lái)說(shuō)一下這個(gè)參數(shù)列表的問(wèn)題

//參數(shù)列表中的第一個(gè)參數(shù) PEnv 類型為 PJNIEnv, 它是 JNI.pas中定義的類型,我們好多工作要通過(guò)它來(lái)實(shí)現(xiàn),可以把它看成是一個(gè)幫你的程序與 Java 溝通的橋梁.

//參數(shù)列表中的第一個(gè)參數(shù) obj 類型為 JObject.前面這兩個(gè)參數(shù)是固定的,這第二個(gè)參數(shù)暫時(shí)我們還不會(huì)用到.

//今天,我們還要給這個(gè)方法多加一個(gè)參數(shù),用來(lái)接受 Java 傳過(guò)來(lái)的參數(shù). str: JString

procedure Java_alvinJNI_HelloWorld_printText(PEnv: PJNIEnv; Obj: JObject; str: JString); stdcall;

//這回我們需要用到一個(gè) TJNIEnv 對(duì)象,我們來(lái)聲明

var

JVM: TJNIEnv;

tmpStr: String;

begin

//實(shí)例化 JVM, 這個(gè)對(duì)象可以看成是 Java 的虛擬機(jī).(自己的理解)

JVM := TJNIEnv.Create(PEnv);

//參數(shù)提交過(guò)來(lái)的字符串,實(shí)際上是一個(gè) JString 對(duì)象,我們?cè)谶@里要用 JVM 來(lái)轉(zhuǎn)化它.

//我們調(diào)用 JVM 的 UnicodeJStringToString 函數(shù)就可以實(shí)現(xiàn) JString 到 String 的轉(zhuǎn)化了.

tmpStr := JVM.UnicodeJStringToString(str);

Writeln(tmpStr);

//我們使用完 JVM 后,要將其釋放.

JVM.Free;

end;

exports

Java_alvinJNI_HelloWorld_printText; //為函數(shù)做引出聲明,這樣才能真正的被調(diào)用到

end.

//----------------------------------------------------------------------------------------------------------

我們現(xiàn)在就可以生成 DelphiAction.dll 將其放在 Java 工程目錄下, 再執(zhí)行 alvinJNI.HelloWorld 看看效果了.

好了,我們今天主要就是實(shí)現(xiàn)了一下,如何在 Java 調(diào)用 Delphi 的方法時(shí),給其提交一個(gè)參數(shù).

是不是很爽?

在上一篇中,我們說(shuō)了如何用 Java 調(diào)用 Delphi 程序的一個(gè)方法并傳遞給其一個(gè)字符串參數(shù),現(xiàn)在我們?cè)賮?lái)看一下如果傳遞的參數(shù)是其它基本類型,又要怎么做.

首先,我們先看一下如何傳遞 int 型參數(shù),定義如下的 Java 類:

//----------------------------------------------------------------------------------------------------------

package alvinJNI;

class HelloWorld {

static {

System.loadLibrary("DelphiAction");

}

public native void printText(int i);

public static void main(String[] args) {

HelloWorld hw = new HelloWorld();

hw.printText(100);

}

}

//----------------------------------------------------------------------------------------------------------

我們?cè)傧裆洗我粯釉?Delphi 中建立 DLL 工程,寫(xiě)下面的代碼(有注釋):

//----------------------------------------------------------------------------------------------------------

library DelphiAction;

uses

JNI;

//我們給這個(gè)方法加的參數(shù)是: i: JInt

procedure Java_alvinJNI_HelloWorld_printText(PEnv: PJNIEnv; Obj: JObject; i: JInt); stdcall;

var

tmpInt: Integer;

begin

//參數(shù)提交過(guò)來(lái)的 int 型數(shù)據(jù),在這里是一個(gè) JInt 數(shù)據(jù),它其實(shí)就是一個(gè) Integer 數(shù)據(jù),它的使用更加方便

//它可以直接地參與 Interger 類型數(shù)據(jù)的運(yùn)算,是不是很容易.

tmpInt := i + 100;

tmpInt := tmpInt - 100;

Writeln(tmpInt);

end;

exports

Java_alvinJNI_HelloWorld_printText;

end.

//----------------------------------------------------------------------------------------------------------

再看看效果吧,是不是成功了?

這里如果是 long 型參數(shù),接收時(shí)要設(shè)為 JLong 類型,它也可以跟對(duì)應(yīng)的整型數(shù)運(yùn)算,我們常用它跟 Int64 一起運(yùn)算

如果參數(shù)類型是 float ,接收參數(shù)時(shí)要設(shè)為 JFloat 類型,它也可以跟跟 Single 一起運(yùn)算

如果參數(shù)類型是 double ,接收參數(shù)時(shí)要設(shè)為 JDouble 類型,它也可以跟跟 Delphi 中的 Double 型數(shù)據(jù)一起運(yùn)算

如果參數(shù)類型是 boolean ,接收參數(shù)時(shí)要設(shè)為 JBoolean 類型,它也可以跟跟 Delphi 中的布爾型數(shù)據(jù)一起運(yùn)算

如果參數(shù)類型是 short ,接收參數(shù)時(shí)要設(shè)為 JShort 類型,它也可以跟跟 SmallInt 型數(shù)據(jù)一起運(yùn)算

如果參數(shù)類型是 byte ,接收參數(shù)時(shí)要設(shè)為 JByte 類型,它也可以跟跟 ShortInt 型數(shù)據(jù)一起運(yùn)算

如果參數(shù)類型是 Object 的 Java 對(duì)象,接收時(shí)要設(shè)為 JObject 類型,它的用法比較復(fù)雜(涉及到對(duì) Java 類和對(duì)象的操作),我們?cè)谝院笤賮?lái)學(xué)習(xí).

如果參數(shù)類型是 Type[] 數(shù)組,接收參數(shù)時(shí)要設(shè)為 JObject 類型,因?yàn)?Java 是把數(shù)組作為對(duì)象看待的.它要以以下的方式來(lái)使用:

例如: 我們要給 Delphi 的方法傳入一個(gè) byte[] 型數(shù)組,在定義 Delphi 方法時(shí)參數(shù)聲明為 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); //調(diào)用這個(gè)方法,可以將取得參數(shù) bytearray 的地址, isCopy 決定是否復(fù)制數(shù)組

//之后,我們可以通過(guò) PByteArr 結(jié)合 inc(PByteArr) 這個(gè)指針來(lái)操作傳過(guò)來(lái)的數(shù)組.

end;

在上一篇中,我們說(shuō)了如何用 Java 調(diào)用 Delphi 程序的一個(gè)方法并傳遞給其一個(gè)參數(shù)

現(xiàn)在我們?cè)賮?lái)看一下如果如果要調(diào)用的方法有返回值,又要怎么做.

首先,我們先定義如下的 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("你好"));

}

}

//-------------------------------------------------------------------------------

我們?cè)傧裆洗我粯釉?Delphi 中建立 DLL 工程,寫(xiě)下面的代碼(有注釋):

//-------------------------------------------------------------------------------

library DelphiAction;

uses

JNI;

//今天,因?yàn)檫@個(gè)方法有返回值,所以不再是 procedure 過(guò)程,我們要變成 function 函數(shù), 返回值類型為 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);

//我們這里先把參數(shù)提交過(guò)來(lái)的 JString 轉(zhuǎn)換成 Delphi 中的 String 后就可以使用了

tmpStr := '你想輸出的字符串是: "' + JVM.UnicodeJStringToString(arg) + '"。';

//當(dāng)字符串要轉(zhuǎn)換成 JString 我們需要先對(duì)字符串進(jìn)行 UTF8 編碼后再轉(zhuǎn)換成 PChar 再轉(zhuǎn)換成 JString

//這樣才能保證返回的字符串在 JAVA 中不亂碼

Result := JVM.StringToJString(pchar(UTF8Encode(tmpStr)));

JVM.Free;

end;

exports

Java_alvinJNI_HelloWorld_printText;

end.

//--------------------------------------------------------------------------------

再看看效果吧,是不是成功了?

這里如果返回值的類型是其它的其本類型,比如 JLong,JInt,JFloat,JDouble,JBoolean,JShort,JByte

這些類型的數(shù)據(jù)可以直接與 Delphi 中的數(shù)據(jù)運(yùn)算,對(duì)應(yīng) Int64,Integer,Single,Double,Boolean,SmallInt,ShortInt

返回時(shí)可以直接給 Result 賦 Delphi 中的數(shù)值. 如:

function Java_alvinJNI_HelloWorld_getInt(PEnv: PJNIEnv; Obj: JObject): JInt; stdcall;

var

tmp: Integer;

begin

tmp := 10;

Result := tmp;

end;

如果返回值的類型是 Object 的 Java 對(duì)象,返回 JObject 類型,它的用法我們?cè)谝院笤賮?lái)學(xué)習(xí).

如果返回值的類型是 Type[] 數(shù)組,接收參數(shù)時(shí)要設(shè)為 JObject 類型,怎樣創(chuàng)建這樣的數(shù)組對(duì)象,我自己也還不知道,以后知道了我再來(lái)貼上

因?yàn)?Java 是把數(shù)組作為對(duì)象看待的.它要以以下的方式來(lái)使用:

例如: 我們要給 Delphi 的方法傳入一個(gè) byte[] 型數(shù)組,在定義 Delphi 方法時(shí)參數(shù)聲明為 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); //調(diào)用這個(gè)方法,可以將取得參數(shù) bytearray 的地址, isCopy 決定是否復(fù)制數(shù)組

//之后,我們可以通過(guò) PByteArr 結(jié)合 inc(PByteArr) 這個(gè)指針來(lái)操作傳過(guò)來(lái)的數(shù)組.

end;

之前,我們學(xué)了如何用 Java 調(diào)用 Delphi 程序的一個(gè)方法

如果在Delphi 程序在適當(dāng)時(shí)候需要調(diào)用 Java 程序,又要怎么做呢?

首先,我們先定義如下的 Java 類:

//------------------------------------------------------------------------------

package alvinJNI;

class HelloWorld {

static {

System.loadLibrary("DelphiAction");

}

String str = "你好";

public native void callPrintText(HelloWorld hw);

public void printText(String arg) {

System.out.println(arg);

}

public static void main(String[] args) {

HelloWorld hw = new HelloWorld();

hw.callPrintText(hw);

}

}

//-------------------------------------------------------------------------------

我們?cè)傧裆洗我粯釉?Delphi 中建立 DLL 工程,寫(xiě)下面的代碼(有注釋):

//-------------------------------------------------------------------------------

library DelphiAction;

uses

JNI;

//今天的這個(gè)程序稍微的復(fù)雜一點(diǎn),因?yàn)橐{(diào)用 Java 對(duì)象的方法,在這里可以學(xué)到對(duì) JObject 的操作

procedure Java_alvinJNI_HelloWorld_callPrintText(PEnv: PJNIEnv; Obj: JObject; arg: JObject); stdcall;

var

JVM: TJNIEnv;

c: JClass; //類ID

fid: JFieldID; //屬性ID

mid: JMethodID; //方法ID

tmpStr: JString;

javaargs : array[0..0] of JValue; //調(diào)用方法時(shí)的參數(shù)

begin

JVM := TJNIEnv.Create(PEnv);

{我們先來(lái)看下如何獲得一個(gè)對(duì)象的某個(gè)屬性值}

{----------------------------------------}

{我們對(duì) Java 對(duì)象的操作要選獲取這個(gè)對(duì)象的 ClassID,我們可以用下面的方法來(lái)取得.}

c := JVM.GetObjectClass(arg);

{我們先來(lái)獲取參數(shù) HelloWorld arg 對(duì)象的 String str 這個(gè)屬性的值

這里我們先要獲得這個(gè)屬性在它所在類中的屬性 ID }

fid := JVM.GetFieldID(c, 'str', 'Ljava/lang/String;');

{上面調(diào)用的這個(gè)方法中的參數(shù)分別是: 所屬類ID, 屬性名, 屬性類型簽名

關(guān)于屬性類型的簽名,將在下面 '說(shuō)明1' 給出}

{下面,我們就可以根據(jù) 屬性ID 來(lái)獲取屬性值了, 這里我們會(huì)取得到 arg.str 這個(gè)字符串}

tmpStr := JVM.GetObjectField(arg, fid);

{上面的這個(gè) JVM.GetObjectField(arg, fid) 用來(lái)獲取屬性值

參數(shù)分別是: 要取得其屬性的對(duì)象, 要取得的屬性的屬性ID

這里取得的是一個(gè) Java 的 String 對(duì)象,是 JString,其實(shí)它也就是 JObject 類型的}

writeln('Delphi 輸出的: ' + JVM.UnicodeJStringToString(tmpStr));

{我們?cè)賮?lái)看下如何調(diào)用一個(gè) JObject 的方法, 這里我們要調(diào)用的是 arg.printText() 這個(gè)方法}

{------------------------------------------------------------------------------------}

//我們還是要用到上面的那個(gè) 類ID: c.

//這一次我們要取得這個(gè)方法的 方法ID

mid := JVM.GetMethodID(c, 'printText', '(Ljava/lang/String;)V');

//上面調(diào)用的這個(gè)方法中的參數(shù)分別是: 所屬類ID, 方法名, 方法(參數(shù)+返回值)類型簽名

//關(guān)于方法(參數(shù)+返回值)類型的簽名,將在下面 '說(shuō)明2' 給出

//有了 方法ID 后我們就可以用這個(gè)ID來(lái)調(diào)用這個(gè)方法了,我們這里要調(diào)用的方法是: arg.printText(參數(shù));

//因?yàn)槲覀円{(diào)用的這個(gè)方法有參數(shù), 調(diào)用 Java 方法的時(shí)候如果有參數(shù),要建立參數(shù)數(shù)組,這里我們就來(lái)建立數(shù)組

javaargs[0].l := tmpStr;

{這里這個(gè) javaargs 是 JValue 類型. 它有點(diǎn)特殊,它的用法在下面 說(shuō)明3 給出}

{有了 類象, 方法ID, 參數(shù). 下面我們就可以調(diào)用 arg.printText(javaargs) 這個(gè)方法了,使用下面這個(gè)方法就可實(shí)現(xiàn)}

JVM.CallObjectMethodA(arg, mid, @javaargs);

JVM.Free;

end;

exports

Java_alvinJNI_HelloWorld_callPrintText;

end.

//--------------------------------------------------------------------------------

到這里,我們已經(jīng)可以從 Delphi 中獲得 Java 對(duì)象的屬性了, 還可以調(diào)用一個(gè) Java 對(duì)象的方法,是不是很酷呢?

你學(xué)到了沒(méi)?

###########################說(shuō)明1###############################

現(xiàn)在,我們還要再了解一個(gè)獲取 "屬性ID" 時(shí)的那個(gè)簽名

上面例子中: fid := JVM.GetFieldID(c, 'str', 'Ljava/lang/String;'); 用的簽名是: 'Ljava/lang/String;'

因?yàn)閯倓傄@得的屬性是 java.lang.String 類型的,所以它的簽名是: 'Ljava/lang/String;'

如果,我們要獲得的屬性是其它類型,獲取 屬性ID 時(shí)又要怎樣簽名呢?下面給出一個(gè)對(duì)照表

byte -- B

char --- C

double -- D

float -- F

int -- I

long -- J (注意:是J不是L)

short -- S

void -- V

boolean - Z(注意:是Z不是B)

class(類對(duì)象類型) - 'L'+完整類名+';' (包路徑分隔符為: '/'. 如上面例子中的 String 對(duì)型, 簽名為: 'Ljava/lang/String;')

數(shù)組 type[] -- '['+type (例如 float[] 的簽名就是 '[float')

(如果是二維數(shù)組,如float[][],則簽名為 '[[float')

############################說(shuō)明2###############################

現(xiàn)在,我們還要再了解一個(gè)獲取 "方法ID" 時(shí)的那個(gè)簽名

上面例子中: mid := JVM.GetMethodID(c, 'printText', '(Ljava/lang/String;)V'); 用的簽名是: '(Ljava/lang/String;)V'

方法ID 的簽名,分為兩部分

一部分是前面括號(hào)中的,是參數(shù)類型的簽名

另一部分是括號(hào)后的,是返回值類型的簽名

其中某個(gè)簽數(shù)與返回值的類型簽名與獲取屬性ID時(shí)的簽名是一樣的

上面要調(diào)用的方法只有一個(gè)參數(shù),如果有多個(gè)參數(shù)時(shí)又怎樣呢?

如: int getInt(long a, double b); 這樣的 Java 方法要這樣簽名: '(JD)I'

(注意:參數(shù)簽名是連續(xù)的,沒(méi)有分隔符, 這里第一個(gè)參數(shù) long 簽名為:J, 第二個(gè)參數(shù)簽名為: D, 返回值類型 int 簽名為: I)

說(shuō)到這里,相信大家都會(huì)使用這個(gè)簽名了

############################說(shuō)明3###############################

在調(diào)用一個(gè) Java 方法時(shí), 如果這個(gè)方法有參數(shù), 我們就要傳遞一個(gè)參數(shù)數(shù)組的地址給 Java

現(xiàn)在,我們還要再了解如何創(chuàng)建這樣的一個(gè)參數(shù)數(shù)組

傳遞給 Java 方法的參數(shù),類型均為 JValue. 它是一個(gè)packed record

如果,我們要調(diào)用的方法 void myMethod(int a, long b, String c); 有 3 個(gè)參數(shù)

那么

1.我們先要聲明如下數(shù)組:

var

args : array[0..1] of JValue;

2.給數(shù)組賦值

args[0].i := 100;

args[1].j := 100;

args[2].l := JVM.StringToJString(pchar(UTF8Encode('開(kāi)源中國(guó)社區(qū) )));

3.調(diào)用

JVM.CallVoidMethodA(Java對(duì)象, 方法ID, @args);

JValue 是一個(gè) packed record,它的定義如下:

JValue = packed record

case Integer of

0: (z: JBoolean);

1: (b: JByte );

2: (c: JChar );

3: (s: JShort );

4: (i: JInt );

5: (j: JLong );

6: (f: JFloat );

7: (d: JDouble );

8: (l: JObject );

end;

調(diào)用方法時(shí),TJNIEnv 還有:

CallObjectMethodA: function(Env: PJNIEnv; Obj: JObject; MethodID: JMethodID; Args: PJValue): JObject; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallBooleanMethodA: function(Env: PJNIEnv; Obj: JObject; MethodID: JMethodID; Args: PJValue): JBoolean; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallByteMethodA: function(Env: PJNIEnv; Obj: JObject; MethodID: JMethodID; Args: PJValue): JByte; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallCharMethodA: function(Env: PJNIEnv; Obj: JObject; MethodID: JMethodID; Args: PJValue): JChar; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallShortMethodA: function(Env: PJNIEnv; Obj: JObject; MethodID: JMethodID; Args: PJValue): JShort; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallIntMethodA: function(Env: PJNIEnv; Obj: JObject; MethodID: JMethodID; Args: PJValue): JInt; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallLongMethodA: function(Env: PJNIEnv; Obj: JObject; MethodID: JMethodID; Args: PJValue): JLong; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallFloatMethodA: function(Env: PJNIEnv; Obj: JObject; MethodID: JMethodID; Args: PJValue): JFloat; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallDoubleMethodA: function(Env: PJNIEnv; Obj: JObject; MethodID: JMethodID; Args: PJValue): JDouble; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallVoidMethodA: procedure(Env: PJNIEnv; Obj: JObject; MethodID: JMethodID; Args: PJValue); {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallNonvirtualObjectMethodA: function(Env: PJNIEnv; Obj: JObject; AClass: JClass; MethodID: JMethodID; Args: PJValue): JObject; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallNonvirtualBooleanMethodA: function(Env: PJNIEnv; Obj: JObject; AClass: JClass; MethodID: JMethodID; Args: PJValue): JBoolean; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallNonvirtualByteMethodA: function(Env: PJNIEnv; Obj: JObject; AClass: JClass; MethodID: JMethodID; Args: PJValue): JByte; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallNonvirtualCharMethodA: function(Env: PJNIEnv; Obj: JObject; AClass: JClass; MethodID: JMethodID; Args: PJValue): JChar; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallNonvirtualShortMethodA: function(Env: PJNIEnv; Obj: JObject; AClass: JClass; MethodID: JMethodID; Args: PJValue): JShort; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallNonvirtualIntMethodA: function(Env: PJNIEnv; Obj: JObject; AClass: JClass; MethodID: JMethodID; Args: PJValue): JInt; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallNonvirtualLongMethodA: function(Env: PJNIEnv; Obj: JObject; AClass: JClass; MethodID: JMethodID; Args: PJValue): JLong; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallNonvirtualFloatMethodA: function(Env: PJNIEnv; Obj: JObject; AClass: JClass; MethodID: JMethodID; Args: PJValue): JFloat; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallNonvirtualDoubleMethodA: function(Env: PJNIEnv; Obj: JObject; AClass: JClass; MethodID: JMethodID; Args: PJValue): JDouble; {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

CallNonvirtualVoidMethodA: procedure(Env: PJNIEnv; Obj: JObject; AClass: JClass; MethodID: JMethodID; Args: PJValue); {$IFDEF MSWINDOWS} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}

更多信息請(qǐng)查看IT技術(shù)專欄

更多信息請(qǐng)查看網(wǎng)絡(luò)編程
易賢網(wǎng)手機(jī)網(wǎng)站地址:Java中調(diào)用Delphi編寫(xiě)的DLL
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

2025國(guó)考·省考課程試聽(tīng)報(bào)名

  • 報(bào)班類型
  • 姓名
  • 手機(jī)號(hào)
  • 驗(yàn)證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡(jiǎn)要咨詢 | 簡(jiǎn)要咨詢須知 | 新媒體/短視頻平臺(tái) | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
云南網(wǎng)警備案專用圖標(biāo)
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號(hào):hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專用圖標(biāo)