Java中調用Delphi編寫的DLL

有些時候,要寫一些程序,在 JAVA 裏面好難實現, 但若是使用其它編程語言卻又比較容易時,咱們不妨經過 JNI 來讓不一樣語言的程序共同完成.
JNI 的教程, 網上 C 的比較多,Java 也提供了 javah.exe 爲 C 語言的 JNI 程序生成頭文件, 若是你是一個 Delphi 編程員, 可否讓 JAVA 與 Delphi 程序交互呢? 答案是確定的,今天咱們就來看一下一個簡單的例子.
Helloworld. 主要是來認識一下, JAVA 怎樣調用 Delphi 程序的方法.java

好的,咱們先來建立一個類:編程

package alvinJNI;數組

class HelloWorld {
static {
System.loadLibrary("DelphiAction"); //等一下咱們就用Delphi來編一個程序,編好以後生成的文件就是 DelphiAction.dll 這是一個動態連接庫文件,這個類裏先在靜態語句塊中加載它
}app

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
解壓以後裏面有兩個文件,將其存放在工程的目錄下.net

接下來咱們編寫 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('開源中國社區 http://www.oschina.net')));
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}

好了,到這裏,相信你們對作 Delphi 的 JNI 已有必定的瞭解 關於 Delphi JNI 的話題就先說到這裏 若是有興趣,你們能夠打開 jni.pas 瞭解更多

相關文章
相關標籤/搜索