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

2014-11-24 03:21:35 · 作者: · 浏览: 1
ARY_PATH(Linux)中。

最后一步我们需要做的是实现调用该本地方法的Java代码,如:

1 package mytest;

2 public class MyTest {

3 //这里调用loadLibrary方法用于加载该动态库到JVM中,以保证在使用时该方法已经被加载。

4 static {

5 System.loadLibrary("HelloNative");

6 }

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

8 HelloNative.greeting();

9 }

10 }

11 /* 输出结果如下:

12 Hello, Native World!

13 */

2. 带有数值类型参数和返回值的本地方法:

先介绍一下Java中原始类型和C语言(JNI)中原始类型之间的对照关系,以及他们所占有的字节数量:

Java语言 C语言 字节数量

boolean jboolean 1

byte jbyte 1

char jchar 2

short jshort 2

int jint  4

long jlong 8

float jfloat 4

double jdouble 8

1) 编写带有native方法的Java代码:

1 package mytest;

2 public class Printf {

3 public static native int print(int width,int precision,double x);

4 static {

5 System.loadLibrary("Printf");

6 }

7 }

2) 编写与native方法对应的C语言代码:(记着先执行命令行命令javah mytest.Printf来生成mytest_Printf.h头文件)

1 #include "mytest_Printf.h"

2 #include

3 JNIEXPORT jint JNICALL Java_mytest_Printf_print(JNIEnv* env, jclass cl

4 ,jint width, jint precision, jdouble x)

5 {

6 char fmt[30];

7 jint ret;

8 sprintf(fmt,"%%%d.%df",width,precision);

9 ret = printf(fmt,x);

10 fflush(stdout);

11 return ret;

12 }

3) 编写调用native方法的Java测试代码:

1 package mytest;

2 public class MyTest {

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

4 int count = Printf.print(8,4,3.14);

5 count += Printf.print(8,4,count);

6 System.out.println();

7 for (int i = 0; i < count; ++i) {

8 System.out.print("-");

9 }

10 System.out.println();

11 }

12 }

13 /* 输出结果如下:

14 3.1400 8.0000

15 ----------------

16 */

3. 带有字符串参数的本地方法:

JNI中提供了一组C语言的函数用于帮助在Java和C之间传递字符串数据,下面的代码会给出详细的注释说明。

1) 编写带有native方法的Java代码:

1 public class Printf {

2 public static native int print(String format,double x);

3 static {

4 System.loadLibrary("Printf");

5 }

6 }

2) 编写与native方法对应的C语言代码:

1 #include "Printf.h"

2 #include

3 #include

4 #include

5 JNIEXPORT jstring JNICALL Java_Printf_print

6 (JNIEnv* env, jclass cl, jstring format, jdouble x)

7 {

8 //1. 这里通过C语言调用JNI本地函数时,需要将参数env解引用之后在调用。

9 //env是指向所有JNI本地函数指针表的指针。

10 //2. 返回"改良UTF-8"编码的字符串的指针,或者当不能构建字符数组时返回NULL。

11 //直到RelaseStringUTFChars函数调用前,该指针一致有效。

12 //3. 由于Java针对字符串使用了对象池的技术,因此这里一定不能修改返回的const char*

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

14 //4. 获取参数中jstring的长度(GetStringUTFLength)

15 char* cret = (char*)calloc(env->GetStringUTFLength(format) + 20,1);

16 sprintf(cret,cformat,x);

17 //5. 根据"改良UTF-8"字节序列,返回一个新的Java对象,或者当字符串构造时,返回NULL。

18 jstr