前言
通过《JNI数据类型及与Java数据类型的映射关系》一文,我们知道了在C中实现java声明的本地方法时,方法入参有其一一对应关系。但在实现方法的方法体中,这些数据类型是否可以拿来直接使用呢?
举个例子,在java文件中声明本地方法如下
public static native void test(short s, int i, long l, float f, double d, char c,
boolean z, byte b, String str, Object obj, MyClass p, int[] arr);
其在c中的对应实现如下
JNIEXPORT void JNICALL Java_com_study_jnilearn_HelloWorld_test
(JNIEnv *env, jclass cls, jshort s, jint i, jlong l, jfloat f,
jdouble d, jchar c, jboolean z, jbyte b, jstring j_str, jobject jobj1, jobject job2, jintArray j_int_arr)
{
...
}
-基本数据类型如jint,jdouble是否可以直接操作?
-可以。
-引用数据类型如jstring,jxxArray是否可以直接操作?
-不可以。JNI接口提供了许多函数来进行这样的转换。
1. C方法中操作jstring
test函数接收一个jstring类型的参数str,但jstring类型是指向JVM内部的一个字符串,和C风格的字符串类型char* 不同,所以在JNI中不能通把jstring当作普通C字符串一样来使用,必须使用合适的JNI函数来访问JVM内部的字符串数据结构。
因为Java默认使用Unicode编码,而C/C++默认使用UTF编码,所以在本地代码中操作字符串的时候,必须使用合适的JNI函数把jstring转换成C风格的字符串。JNI支持字符串在Unicode和UTF-8两种编码之间转换。
GetStringUTFChars可以把一个jstring指针(指向JVM内部的Unicode字符序列)转换成一个UTF-8格式的C字符串。在上例中test函数中我们通过GetStringUTFChars正确取得了JVM内部的字符串内容。
1.1 操作步骤
GetStringUTFChars(env, j_str, &isCopy) 访问字符串。
isCopy:取值JNI_TRUE和JNI_FALSE,如果值为JNI_TRUE,表示返回JVM内部源字符串的一份拷贝,并为新产生的字符串分配内存空间。如果值为JNI_FALSE,表示返回JVM内部源字符串的指针,意味着可以通过指针修改源字符串的内容,不推荐这么做,因为这样做就打破了Java字符串不能修改的规定。但我们在开发当中,并不关心这个值是多少,通常情况下这个参数填NULL即可。
异常检查。
调用完GetStringUTFChars之后不要忘记安全检查, if(c_str =