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 了解更多

相关文章
相关标签/搜索