Java中的数组在jni中是jxxxArray类型,如jintArray
。
获取array长度
不同于c/c++语言,jni中获取array长度需要使用JNIEnv对象方法GetArrayLength(env, array)
来获取。
// 获取数组长度的不同语言不同方法
//c-宏
#define GET_ARRAY_LENGTH(array, len) {len = (sizeof(array)/sizeof(array[0]));}
//c++-模板
template <class T>
int getArrayLength(T& array)
{
return sizeof(array) / sizeof(array[0]);
}
// jni-sum example
jint getSum(JNIEnv *env, jintArray values)
{
int i, sum=0;
int length = (*env)->GetArrayLength(env, values);
jint *body = (*env)->GetIntArrayElements(env, values, 0);
for(i=0;i<length;i++)
{
sum += body[i];
}
(*env)->ReleaseIntArrayElements(env, values, body, 0);
return sum;
}
jintArray
一般我们使用jintArray需要下面几部(代码在上面的例子中):
- GetArrayLength
获取数组长度。
- GetIntArrayElements
获取指向数组的指针。
- 使用c语言通常方法访问数组成员。
- 使用结束后使用ReleaseIntArrayElements
释放指针。
字符串数组的一个例子
// 合并字符串数组为一个字符串,每个子串之间用“#分隔
int getStringLen(JNIEnv *, jobjectArray);
void joinStrings(JNIEnv *, char*, jobjectArray);
JNIEXPORT jstring JNICALL Java_com_mislead_testjni_TestJni_joinStrings
(JNIEnv *env, jobject jobj, jobjectArray strs)
{
int outLen=getStringLen(env, strs);
char result[outLen];
joinStrings(env, result, strs);
return (*env)->NewStringUTF(env, result);
}
int getStringLen(JNIEnv *env, jobjectArray strs)
{
int i, len = 0;
int array_len = (*env)->GetArrayLength(env, strs);
for (i=0;i<array_len;i++)
{
jobject obj=(*env)->GetObjectArrayElement(env, strs, i);
len+=(*env)->GetStringUTFLength(env, (jstring) obj);
}
//因为有分隔字符所以这里我们计算总长度的时候要加上分隔字符数量(这里不严谨)
return len + array_len;
}
void joinStrings(JNIEnv *env, char *out, jobjectArray strs)
{
int array_len=(*env)->GetArrayLength(env, strs);
int i;
for (i=0;i<array_len;i++)
{
jstring jword=(jstring)(*env)->GetObjectArrayElement(env, strs, i);
const char *word=(*env)->GetStringUTFChars(env, jword, 0);
if(i>0)
{
//拼接字符串
LOGE("%d:%s", i, out);
strcat(out, "#");
strcat(out, word);
}
else
{
//复制字符串
strcpy(out, word);
}
(*env)->ReleaseStringUTFChars(env, jword, word);
}
}