转自:http://www.blogjava.net/alvin/archive/2006/12/13/87371.html
先贴过来 慢慢看
============================================
通过 JNI 让 JAVA 与 Delphi 程序交互
之前,我们学了如何用 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://download.csdn.net/source/1527720