中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

Java中調用Delphi編寫的DLL
來源:易賢網 閱讀:1072 次 日期:2015-04-10 15:11:53
溫馨提示:易賢網小編為您整理了“Java中調用Delphi編寫的DLL”,方便廣大網友查閱!

有些時候,要寫一些程序,在 JAVA 里面好難實現, 但如果使用其它編程語言卻又比較容易時,我們不妨通過 JNI 來讓不同語言的程序共同完成.

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

Helloworld. 主要是來認識一下, JAVA 怎樣調用 Delphi 程序的方法.

好的,我們先來創建一個類:

package alvinJNI;

class HelloWorld {

static {

System.loadLibrary("DelphiAction"); //等一下我們就用Delphi來編一個程序,編好之后生成的文件就是 DelphiAction.dll 這是一個動態鏈接庫文件,這個類里先在靜態語句塊中加載它

}

public native void printText(); //聲明一個 native 的本地代碼程序,我們使用的是 Delphi 來編寫.注意:這個方法在這里只是聲明,并沒有定義方法體,因為這個方法我們要用 Delphi 來實現.

public static void main(String[] args) {

//創建對象并調用里面的 native 方法.

HelloWorld hw = new HelloWorld();

hw.printText();

}

}

類寫完編譯后,接下來的事情就由 Delphi 來解決了

我們運行 Delphi 后新建 DLL 工程: file->new->other,然后在 new 選項卡里面選擇 Dll Wizard 就創建了一個新的工程了,

我們選擇一個文件夾來保存工程

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

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

接下來我們編寫 Delphi 代碼:

library DelphiAction; //這里設置動態鏈接庫的名稱,因為我們剛才寫 JAVA 類時是用 DelphiAction,所以這里了要設置為 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. 這里面都是注釋,是自動生成的,可以刪去 }

Uses

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

//下面我們來寫一個函數,就是為 剛才 JAVA 類實現一個簡單的方法

//因為要讓 JAVA 能夠調用到這個函數,所以這個函數的命名是非常講究的,名稱各段的分隔符是 _ 下劃線

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

//函數必須設置為 stdcall

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

begin

//函數體非常簡單,因為我們只是了解一下如何調用 Delphi 的函數.

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

end;

exports

Java_alvinJNI_HelloWorld_printText; //為函數做引出聲明,這樣才能真正的被調用到

end.

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

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

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

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

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

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

然后在 C:/test 目錄中執行: java alvinJNI/HelloWorld

看看你的 Java 程序調用了 DelphiAction 是怎么樣的效果.

呵呵,爽吧! 今天我們才做了一點點,只學了一下如何在 JAVA 調用 Delphi 和程序,在接下來,我會貼出更多的教程,以學習一些高級一點點的 JNI 知識.

現在難得來看一下自己的博客,今天好不容易找了個代理,順便再繼續之前的話題,就是 JAVA 與 Delphi 的交互了.

在上一篇中,我們說了如何用 Java 調用 Delphi 程序的一個方法,今天我們再深入一點,就是怎樣提交參數個 Delphi 的方法,以動態的控制 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("您好!看到效果了吧。");

}

}

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

我們再像上次一樣在 Delphi 中建立 DLL 工程,寫下面的代碼(有注釋):

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

library DelphiAction;

uses

JNI;

//這一次我們要寫的這個方法因為要接收一個 Java 傳過來的參數,所以我們來說一下這個參數列表的問題

//參數列表中的第一個參數 PEnv 類型為 PJNIEnv, 它是 JNI.pas中定義的類型,我們好多工作要通過它來實現,可以把它看成是一個幫你的程序與 Java 溝通的橋梁.

//參數列表中的第一個參數 obj 類型為 JObject.前面這兩個參數是固定的,這第二個參數暫時我們還不會用到.

//今天,我們還要給這個方法多加一個參數,用來接受 Java 傳過來的參數. str: JString

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

//這回我們需要用到一個 TJNIEnv 對象,我們來聲明

var

JVM: TJNIEnv;

tmpStr: String;

begin

//實例化 JVM, 這個對象可以看成是 Java 的虛擬機.(自己的理解)

JVM := TJNIEnv.Create(PEnv);

//參數提交過來的字符串,實際上是一個 JString 對象,我們在這里要用 JVM 來轉化它.

//我們調用 JVM 的 UnicodeJStringToString 函數就可以實現 JString 到 String 的轉化了.

tmpStr := JVM.UnicodeJStringToString(str);

Writeln(tmpStr);

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

JVM.Free;

end;

exports

Java_alvinJNI_HelloWorld_printText; //為函數做引出聲明,這樣才能真正的被調用到

end.

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

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

好了,我們今天主要就是實現了一下,如何在 Java 調用 Delphi 的方法時,給其提交一個參數.

是不是很爽?

在上一篇中,我們說了如何用 Java 調用 Delphi 程序的一個方法并傳遞給其一個字符串參數,現在我們再來看一下如果傳遞的參數是其它基本類型,又要怎么做.

首先,我們先看一下如何傳遞 int 型參數,定義如下的 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);

}

}

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

我們再像上次一樣在 Delphi 中建立 DLL 工程,寫下面的代碼(有注釋):

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

library DelphiAction;

uses

JNI;

//我們給這個方法加的參數是: i: JInt

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

var

tmpInt: Integer;

begin

//參數提交過來的 int 型數據,在這里是一個 JInt 數據,它其實就是一個 Integer 數據,它的使用更加方便

//它可以直接地參與 Interger 類型數據的運算,是不是很容易.

tmpInt := i + 100;

tmpInt := tmpInt - 100;

Writeln(tmpInt);

end;

exports

Java_alvinJNI_HelloWorld_printText;

end.

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

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

這里如果是 long 型參數,接收時要設為 JLong 類型,它也可以跟對應的整型數運算,我們常用它跟 Int64 一起運算

如果參數類型是 float ,接收參數時要設為 JFloat 類型,它也可以跟跟 Single 一起運算

如果參數類型是 double ,接收參數時要設為 JDouble 類型,它也可以跟跟 Delphi 中的 Double 型數據一起運算

如果參數類型是 boolean ,接收參數時要設為 JBoolean 類型,它也可以跟跟 Delphi 中的布爾型數據一起運算

如果參數類型是 short ,接收參數時要設為 JShort 類型,它也可以跟跟 SmallInt 型數據一起運算

如果參數類型是 byte ,接收參數時要設為 JByte 類型,它也可以跟跟 ShortInt 型數據一起運算

如果參數類型是 Object 的 Java 對象,接收時要設為 JObject 類型,它的用法比較復雜(涉及到對 Java 類和對象的操作),我們在以后再來學習.

如果參數類型是 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;

在上一篇中,我們說了如何用 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;

之前,我們學了如何用 Java 調用 Delphi 程序的一個方法

如果在Delphi 程序在適當時候需要調用 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);

}

}

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

我們再像上次一樣在 Delphi 中建立 DLL 工程,寫下面的代碼(有注釋):

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

library DelphiAction;

uses

JNI;

//今天的這個程序稍微的復雜一點,因為要調用 Java 對象的方法,在這里可以學到對 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; //調用方法時的參數

begin

JVM := TJNIEnv.Create(PEnv);

{我們先來看下如何獲得一個對象的某個屬性值}

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

{我們對 Java 對象的操作要選獲取這個對象的 ClassID,我們可以用下面的方法來取得.}

c := JVM.GetObjectClass(arg);

{我們先來獲取參數 HelloWorld arg 對象的 String str 這個屬性的值

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

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

{上面調用的這個方法中的參數分別是: 所屬類ID, 屬性名, 屬性類型簽名

關于屬性類型的簽名,將在下面 '說明1' 給出}

{下面,我們就可以根據 屬性ID 來獲取屬性值了, 這里我們會取得到 arg.str 這個字符串}

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

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

參數分別是: 要取得其屬性的對象, 要取得的屬性的屬性ID

這里取得的是一個 Java 的 String 對象,是 JString,其實它也就是 JObject 類型的}

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

{我們再來看下如何調用一個 JObject 的方法, 這里我們要調用的是 arg.printText() 這個方法}

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

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

//這一次我們要取得這個方法的 方法ID

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

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

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

//有了 方法ID 后我們就可以用這個ID來調用這個方法了,我們這里要調用的方法是: arg.printText(參數);

//因為我們要調用的這個方法有參數, 調用 Java 方法的時候如果有參數,要建立參數數組,這里我們就來建立數組

javaargs[0].l := tmpStr;

{這里這個 javaargs 是 JValue 類型. 它有點特殊,它的用法在下面 說明3 給出}

{有了 類象, 方法ID, 參數. 下面我們就可以調用 arg.printText(javaargs) 這個方法了,使用下面這個方法就可實現}

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

JVM.Free;

end;

exports

Java_alvinJNI_HelloWorld_callPrintText;

end.

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

到這里,我們已經可以從 Delphi 中獲得 Java 對象的屬性了, 還可以調用一個 Java 對象的方法,是不是很酷呢?

你學到了沒?

###########################說明1###############################

現在,我們還要再了解一個獲取 "屬性ID" 時的那個簽名

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

因為剛剛要獲得的屬性是 java.lang.String 類型的,所以它的簽名是: 'Ljava/lang/String;'

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

byte -- B

char --- C

double -- D

float -- F

int -- I

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

short -- S

void -- V

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

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

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

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

############################說明2###############################

現在,我們還要再了解一個獲取 "方法ID" 時的那個簽名

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

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

一部分是前面括號中的,是參數類型的簽名

另一部分是括號后的,是返回值類型的簽名

其中某個簽數與返回值的類型簽名與獲取屬性ID時的簽名是一樣的

上面要調用的方法只有一個參數,如果有多個參數時又怎樣呢?

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

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

說到這里,相信大家都會使用這個簽名了

############################說明3###############################

在調用一個 Java 方法時, 如果這個方法有參數, 我們就要傳遞一個參數數組的地址給 Java

現在,我們還要再了解如何創建這樣的一個參數數組

傳遞給 Java 方法的參數,類型均為 JValue. 它是一個packed record

如果,我們要調用的方法 void myMethod(int a, long b, String c); 有 3 個參數

那么

1.我們先要聲明如下數組:

var

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

2.給數組賦值

args[0].i := 100;

args[1].j := 100;

args[2].l := JVM.StringToJString(pchar(UTF8Encode('開源中國社區 )));

3.調用

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

JValue 是一個 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;

調用方法時,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}

更多信息請查看IT技術專欄

更多信息請查看網絡編程
易賢網手機網站地址:Java中調用Delphi編寫的DLL
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
欧美精品一区二| 欧美sm视频| 久久久国产亚洲精品| 国产精品久久久久久超碰 | 国产精品久久久久9999高清| 日韩亚洲在线观看| 欧美日韩综合视频| 午夜精品一区二区三区电影天堂 | 欧美 日韩 国产精品免费观看| 一区二区三区自拍| 欧美国产日韩a欧美在线观看| 99re在线精品| 国产精品一级| 免费在线亚洲欧美| 一区二区电影免费观看| 国产一区二区三区丝袜| 欧美精品www在线观看| 亚洲综合第一页| 黑人极品videos精品欧美裸| 欧美电影在线观看| 欧美亚洲午夜视频在线观看| 在线精品国产欧美| 国产精品欧美日韩一区| 欧美88av| 久久露脸国产精品| 亚洲欧美日韩中文播放| 日韩视频在线一区二区| 雨宫琴音一区二区在线| 国产亚洲二区| 国产欧美日韩在线观看| 欧美午夜精品久久久久久人妖| 免费观看一区| 久久久亚洲精品一区二区三区| 亚洲欧美激情精品一区二区| 日韩一区二区电影网| 亚洲电影网站| 亚洲国产va精品久久久不卡综合| 国产欧美一区二区精品婷婷| 国产精品啊v在线| 欧美网站在线观看| 欧美日韩视频一区二区| 欧美精品一区在线观看| 嫩模写真一区二区三区三州| 久久久久久久成人| 久久精品国产久精国产一老狼| 亚洲欧美在线另类| 亚洲欧美日本视频在线观看| 亚洲自拍电影| 亚洲免费小视频| 午夜伦欧美伦电影理论片| 亚洲一区bb| 亚洲女人天堂成人av在线| 99热精品在线| 亚洲无亚洲人成网站77777| 99在线精品免费视频九九视| 亚洲精品国产精品国产自| 在线观看日韩av先锋影音电影院| 国产在线麻豆精品观看| 韩日精品在线| 国产亚洲毛片在线| 国产欧美日韩精品一区| 欧美日韩专区| 欧美三级午夜理伦三级中文幕| 欧美黄色网络| 欧美喷水视频| 欧美一区二区在线免费观看| 在线视频你懂得一区| 亚洲一二三区精品| 亚洲最快最全在线视频| 亚洲欧美日韩中文视频| 亚洲主播在线| 久久亚洲欧美| 美女任你摸久久| 欧美日韩亚洲国产精品| 欧美日韩国产免费| 国产免费亚洲高清| 国产精品午夜视频| 狠狠色狠狠色综合人人| 国内精品免费午夜毛片| 亚洲破处大片| 亚洲精品小视频在线观看| 亚洲少妇诱惑| 亚洲欧美视频一区二区三区| 久久久精品国产一区二区三区| 久久乐国产精品| 中日韩美女免费视频网址在线观看| 日韩视频二区| 精品88久久久久88久久久| 91久久国产综合久久| 亚洲激情六月丁香| 午夜一级久久| 久久人人97超碰人人澡爱香蕉| 欧美日韩视频一区二区| 国产精品色午夜在线观看| 在线看一区二区| 日韩亚洲视频在线| 久久久久久噜噜噜久久久精品| 久久伊人亚洲| 国产精品一区二区在线观看不卡 | 亚洲黄色视屏| 亚洲欧美一区二区在线观看| 午夜精品久久久久久久99水蜜桃 | 国产精品视频一二三| 国产精品久久久一区二区三区| 国产一区二区三区久久| 在线成人黄色| 欧美一区二区三区啪啪| 麻豆精品在线视频| 国产一区二区三区免费不卡| 91久久精品日日躁夜夜躁国产| 久久精品国产清自在天天线| 欧美11—12娇小xxxx| 狠狠色综合色区| 正在播放日韩| 欧美日在线观看| 国产欧美一区二区三区沐欲| 亚洲乱码视频| 欧美有码视频| 国产亚洲欧美色| 亚洲精品久久久久久下一站| 久久久噜噜噜久久中文字幕色伊伊 | 国产亚洲激情视频在线| 激情视频一区二区三区| 久久精品女人| 欧美调教vk| 一区二区欧美精品| 美腿丝袜亚洲色图| 亚洲第一主播视频| 新67194成人永久网站| 国产精品嫩草久久久久| 亚洲电影自拍| 久久综合精品一区| 国产欧美一区二区精品秋霞影院| 午夜电影亚洲| 欧美日韩免费| 亚洲在线视频网站| 葵司免费一区二区三区四区五区| 一区视频在线播放| 欧美在线免费观看视频| 激情偷拍久久| 久久国产精品久久久| 一色屋精品视频在线看| 亚洲欧美99| 狠狠色2019综合网| 欧美在线视频不卡| 亚洲高清久久网| 美女黄网久久| 日韩亚洲欧美成人| 欧美金8天国| 午夜亚洲视频| 国产精品视频xxxx| 久久久久久久999精品视频| 国产精品免费一区豆花| 欧美主播一区二区三区| 欧美日韩国产色视频| 午夜久久影院| 国产精品mv在线观看| 久久福利资源站| 国产精品第2页| 久久精品国产精品亚洲综合| 国产精品国产三级国产专播品爱网 | 久久婷婷影院| 国内久久视频| 久久网站热最新地址| 日韩午夜在线观看视频| 欧美四级在线观看| 久久久青草青青国产亚洲免观| 国产综合婷婷| 国产精品av免费在线观看| 亚洲亚洲精品三区日韩精品在线视频| 国产美女精品一区二区三区| 性视频1819p久久| 日韩视频在线播放| 欧美婷婷在线| 欧美不卡在线| 亚洲无吗在线| 99re热精品| 国产女人精品视频| 欧美三级第一页| 欧美影院在线| 亚洲一区在线免费观看| 欧美日韩在线电影| 免费久久99精品国产| 亚洲国产精品电影在线观看| 国产精品女主播在线观看| 99www免费人成精品| 黑人一区二区| 欧美成人精品在线| 久久人人爽人人爽爽久久| 夜夜嗨av色综合久久久综合网| 国产亚洲一级高清| 亚洲欧美综合国产精品一区| 亚洲精品一区在线观看| 欧美亚洲日本国产| 亚洲精品日韩在线观看| 在线观看精品| 国产精品毛片| 国产精品另类一区| 欧美成年视频| 免费观看不卡av|