Step By Step(Java 本地方法篇) (五)

2014-11-24 03:21:35 · 作者: · 浏览: 4
class class_X = 0;

2 static jfieldID id_a;

3 ...

4 if (class_X == 0) {

5 jclass cx = env->GetObjectClass(obj);

6 class_X = env->NewGlobalRef(cx);

7 id_a = env->GetFieldID(env,cls,"a","...");

8 }

然而需要注意的是,在结束对类的使用时,务必调用:env->DeleteGlobalRef(class_X)来通知JVM释放该资源。

3) 含有main函数的调用测试代码:

1 public class MyTest {

2 public static void main(String[] args) throws Exception {

3 Employee[] staff = new Employee[3];

4 staff[0] = new Employee("Harry Hacker",35000);

5 staff[1] = new Employee("Carl Cracker",75000);

6 staff[2] = new Employee("Tony Tester",38000);

7 for (Employee e : staff)

8 e.raiseSalary(5);

9 for (Employee e : staff)

10 e.print();

11 }

12 }

13 /* 输出结果如下:

14 Harry Hacker 71750.0

15 Carl Cracker 153750.0

16 Tony Tester 77900.0

17 */

7. 编码签名:

为了访问实例域和调用Java编程语言中定义的方法,你必须学习"编入"数据类型的名称和方法签名的规则,见如下编码方案:

B byte

C char

D double //如下例中env->GetFieldID(class_Employee,"salary","D");

F float

I int

J long

S short

V void

Z boolean

Lclassname; 类的类型

如果描述数组类型,需要使用[,如果二维数组[[,以此类推。如:

[Ljava/lang/String; //String一维数组

[[F //float[][]二维数组

要建立一个方法的完整签名,需要把括号内的参数类型都列出来,然后列出返回值类型,如:

(II)I //一个接收两个整型参数并返回一个整数的方法编码。

上例中的print方法的签名是:(Ljava/lang/String;)V //表示该方法接收一个字符串String参数,返回值为void。

注意,在L表达式结尾处的分号是类型表达式的终止符,而不是参数之间的分隔符,如上例中Employee的构造函数:

Employee(java.lang.String,double,java.util.Date); 具有如下签名:

(Ljava/lang/String;DLjava/util/Date;)V

可以看到在D和Ljava/util/Date;之间没有分隔符。另外要注意在这个编码方案中,必须用/代替.来分隔包名和类名。结尾的V表示返回类型为void。即使对Java的构造器没有指定返回类型,也需要将V添加到JVM签名中。

8. 调用Java非静态方法:

Java中可以通过JNI调用native的C语言方法,同样JNI也提供了方法可以让C语言中的方法调用Java的方法,见下例:

1) 包含native方法的Java类代码:

1 import java.io.PrintWriter;

2 public class Printf {

3 public static native void fprint(PrintWriter out,String format,double x);

4 static {

5 System.loadLibrary("Printf");

6 }

7 }

2) 实现本地方法的C语言代码:

1 #include "Printf.h"

2 #include

3 #include

4 #include

5

6 JNIEXPORT void JNICALL Java_Printf_fprint

7 (JNIEnv* env, jclass cl, jobject out, jstring format, jdouble x)

8 {

9 const char* cformat = env->GetStringUTFChars(format,NULL);

10 char* cstr = (char*)calloc(strlen(cformat) + 20,sizeof(char));

11 sprintf(cstr,cformat,x);

12 jstring str = env->NewStringUTF(cstr);

13 free(cstr);

14 env->ReleaseStringUTFChars(format,cformat);

15

16 jclass class_PrintWriter = env->GetObjectClass(out);

17 //对应于void PrintWrite.print(String)方法

18 jmethodID id_print = env->GetMethodID(class_PrintWriter,"print","(Ljava/lang/String;)V");

19 //这里Void是CallXxxMethod一组方法中的一个,表示调用函数的返回值类型。

20 //因此该方法的返回值也是void,如果调用CallIntMethod,其返回值将为jint。

21 env->CallVoidMethod(out,id_print,str);

22 }

3) 含有main函数的调用测试代码:

1 import java.io.PrintWriter;

2 public cla