函数 |
Java数组本地C/C++类型 |
Java本地C/C++类型 |
GetBooleanArrayElements |
jbooleanArray |
Jboolean |
GetByteArrayElements |
jbyteArray |
Jbyte |
GetCharArrayElements |
jcharArray |
Jchar |
GetShortArrayElements |
jshortArray |
Jshort |
GetIntArrayElements |
jintArray |
Jint |
GetLongArrayElements |
jlongArray |
Jlong |
GetFloatArrayElements |
jfloatArray |
Jfloat |
GetDoubleArrayElements |
jdoubleArray |
Jdouble |
JNIEXPORT jobjectArray JNICALL Java_com_robin_HelloActivity_getStringArrayFromJni
(JNIEnv *env, jobject thiz)
{
jstring str;
jobjectArray args = 0;
jsize len = 5;
char* sa[] = { "Hello,", "world!", "This", "is", "robin" };
int i=0;
args = (env)->NewObjectArray(len,(env)->FindClass("java/lang/String"),0);
for( i=0; i < len; i++ )
{
str = (env)->NewStringUTF(sa[i] );
(env)->SetObjectArrayElement(args, i, str);
}
return args;
}
二维数组和String数组
在JNI中,二维数组和String数组都被视为object数组,因为数组和String被视为object。仍然用一个例子来说明,这次是一个二维int数组,作为返回值。
JNIEXPORT jobjectArray JNICALL Java_ObjectArrayTest_initInt2DArray(JNIEnv *env, jclass cls, int size)
{
jobjectArray result;
jclass intArrCls = env->FindClass("[I");
result = env->NewObjectArray(size, intArrCls, NULL); //为result分配空间
for (int i = 0; i < size; i++) {
jint tmp[256]; /* make sure it is large enough! */
jintArray iarr = env->NewIntArray(size); //为一维int数组iarr分配空间
for(int j = 0; j < size; j++) {
tmp[j] = i + j;
}
env->SetIntArrayRegion(iarr, 0, size, tmp); //为iarr赋值
env->SetObjectArrayElement(result, i, iarr); //result的第i个元素赋值
env->DeleteLocalRef(iarr);
}
return result;
}
上面代码中的第三行,
jobjectArray result;
因为要返回值,所以需要新建一个jobjectArray对象。
jclass intArrCls = env->FindClass("[I");
是创建一个jclass的引用,因为result的元素是一维int数组的引用,所以intArrCls必须是一维int数组的引用,这一点是如何保证的呢?注意FindClass的参数"[I",JNI就是通过它来确定引用的类型的,I表示是int类型,[标识是数组。对于其他的类型,都有相应的表示方法,
Z boolean
B byte
C char
S short
I int
J long
F float
D double
String是通过“Ljava/lang/String;”表示的,那相应的,String数组就应该是“[Ljava/lang/String;”。
"二维数组和String数组"这部分所用到的函数调用方式都是针对C++的,如果要在C中使用,所有的env->都要被替换成(*env)->,而且后面的函数中需要增加一个参数env