Java中调用Delphi编写的DLL(4)

到这里,我们已经可以从 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('Linux公社 ')));
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}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwsfjy.html