第三部分 Java与C的参数传递
参数所有类型的对应关系表
摘自Wikipedia(en)
Native Type | Java Language Type | Description | Type signature |
unsigned char | jboolean | unsigned 8 bits | Z |
signed char | jbyte | signed 8 bits | B |
unsigned short | jchar | unsigned 16 bits | C |
short | jshort | signed 16 bits | S |
long | jint | signed 32 bits | I |
long long__int64 | jlong | signed 64 bits | J |
float | jfloat | 32 bits | F |
double | jdouble | 64 bits | D |
void | V |
第一个例子——基本参数的传递
这里引用 Ken Slonneger 的经典案例说明
Java程序如下:
//:Compute.java
public class Compute {
static native double compute(int m, int n); // 注意:这里定义的本地方法(函数)入口有 m,n 两个 int 型变量
static {
System.loadLibrary("ComputeJNI");
}
public static void main(String[] args) {
double answer = compute(45, 67); // 这里与C语言中调用函数的方法类似
System.out.println("answer = " + answer);
}
}
C程序如下:
/* answer.c */
#include "Compute.h"
JNIEXPORT jdouble JNICALL
Java_Compute_compute (JNIEnv *env, jclass jClass, jint m, jint n)
{
//assumes method is overloaded
jdouble result = m + n + 100; // 定义该方法(函数)的返回值
return result;
}
最终运行结果为
answer = 212.0
第二个例子——字符串参数的传递
通过对应表,我们可以发现,Java中的String类型并没有与之对应的本地类型(即C无法通过JNI直接操作),那么如果我们想在设计的Java与C程序之间传递字符串该怎么办呢?这里我写了一个简单的程序来说明基本思路:
Java程序如下:
//: JNITest.java
import java.io.*;
public class JNITest { // 一个简单的从键盘读取输入字符串并最终打印输出到屏幕的程序
static native String listen(String str); // 注意:这里定义的入口参数是String类型
static {
System.loadLibrary("JNITest");
}
public static void main(String [] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str1 = null;
String str2 = null;
System.out.println("Enter the string: ");
str1 = br.readLine();
str2 = listen(str1);
System.out.println("My string is: " + str1);
}
}
C程序如下:
/* listen.c */
#include "JNITest.h"
JNIEXPORT jstring JNICALL Java_JNITest_listen
(JNIEnv *env, jclass jClass, jstring javaString)
{
/*Get the native string from javaString*/
const char *nativeString = (*env)->GetStringUTFChars(env, javaString, 0); // 注意:利用该函数可以实现从String到char*的转换
/*Do something with the nativeString*/
char *rtn = malloc(1024); // 注意:这里一定要定义一个新的char*来储存取得的字符串
memcpy(rtn,nativeString,(sizeof(nativeString)+1)); // 直接送给返回值
/*DON'T FORGET THIS LINE!!!*/
(*env)->ReleaseStringUTFChars(env, javaString, nativeString); // 注意:这里用来回收,与GetStringUTFChars相对应,不要忘记写
return rtn;
}
最终运行结果为
Enter the string:
test
My string is: test
其他常用的JNI函数介绍
有关更多JNI下操作的函数,可以参考这篇文章:http://blog.csdn.net/qinjuning/article/details/7595104