参考:《Java核心技术 卷II:高级特性》第12章 本地方法
##########################################################################
当在C和Java之间传递数字时,应该知道它们彼此之间的对应类型。例如,尽管C拥有int和long的数据类型,但是它们的实现却是取决于平台的。在一些平台上,int类型是16位的,在另外一些平台上是32位的。当然,在Java平台上int类型总是32位的整数。基于这个原因,Java本地接口定义了jint,jlong等类型。
Java数据类型和C数据类型 | |||||
Java编程语言 | C编程语言 | 字节 | Java编程语言 | C编程语言 | 字节 |
boolean | jboolean | 1 | int | jint | 4 |
byte | jbyte | 1 | long | jlong | 8 |
char | jchar | 2 | float | jfloat | 4 |
short | jshort | 2 | double | jdouble | 8 |
在头文件jni.h中,这些类型被typedef 语句声明为在目标平台上等价的类型。该头文件也定义了常量JNI_FALSE=0和JNI_TRUE=1
########################################################################33
用printf格式化数字
直到Java SE 5.0,Java才有了与C语言的printf函数相类似的方法。在下面的示例中,我们假设使用古老版本的JDK,并且决定通过调用本地函数中的C的printf函数来实现同样的功能。
Printf1.java
/**
* @time:15-11-8
* @author:zj
**/
class Printf1 {
public static native int print(int width, int precision, double x);
static {
System.loadLibrary("Printf1");
}
}
注意:用C实现该方法时,所有的int和double参数都要转换成jint和jdouble
printf1.c
/**
* @time:15-11-8
* @author:zj
**/
#include "Printf1.h"
#include <stdio.h>
JNIEXPORT jint JNICALL Java_Printf1_print
(JNIEnv *env, jclass cl, jint width, jint precision, jdouble x) {
char fmt[30];
jint ret;
sprintf(fmt, "%%%d.%df", width, precision);
ret = printf(fmt, x);
fflush(stdout);
return ret;
}
该函数仅仅装配变量fmt中的格式字符串“%w.pf”,然后调用printf函数,接着返回打印出的字符的个数。
验证Printf1类的测试程序
Printf1Test.java
/**
* @time:15-11-8
* @author:zj
**/
class Printf1Test {
public static void main(String[] args) {
int count = Printf1.print(8, 4, 3.14);
count += Printf1.print(8, 4, count);
System.out.println();
for (int i=0; i<count; i++)
System.out.print("-");
System.out.println();
}
}
编译后,运行
java -Djava.library.path=. Printf1Test