public class ObjectArrayTest{
public static native int[][] init2DArray(int size); //声明本地方法
public static void main(String[] args) {
int i2arr[][] = init2DArray(3);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(" "+i2arr[i][j]);
}
System.out.print(" ");
}
}
static{
//System.loadLibrary("helloworld"); // 加载库文件
System.load("/Users/zhaoshun/solibs/libObjectArrayTest.so");
}
}
/**
原型
* Class: jni_sample_ObjectArrayTest
* Method: init2SArray
* Signature: (I)[[I
*
JNIEXPORT jobjectArray JNICALL Java_jni_sample_ObjectArrayTest_init2DArray(JNIEnv *, jclass, jint);
输出结果:
0 1 2 1 2 3 2 3 4
*/
#include <jni.h>
#include <stdio.h>
#include "jni_sample_ObjectArrayTest.h"
// printf 在stdio.h头文件中
JNIEXPORT jobjectArray JNICALL Java_jni_sample_ObjectArrayTest_init2DArray(JNIEnv *env, jclass cls, jint size)
{
jobjectArray result;
int i;
jclass intArrCls = (*env)->FindClass(env,"[I");
if(intArrCls == NULL){
return NULL; /* exception thrown */
}
result = (*env)->NewObjectArray(env,size,intArrCls,NULL);
if(result == NULL){
return NULL; /* out of memory error thrown */
}
for (i = 0;i<size;i++) {
jint tmp[256]; /* make sure it is large enough! */
int j;
jintArray iarr = (*env)->NewIntArray(env,size);
if(iarr == NULL){
return NULL;
}
for (j=0;j<size;j++) {
tmp[j] = i+j;
}
(*env)->SetIntArrayRegion(env, iarr, 0, size, tmp);
(*env)->SetObjectArrayElement(env, result, i, iarr);
(*env)->DeleteLocalRef(env, iarr);
}
return result;
}
/**
newInt2DArray方法首先调用FindClass获得一个一维int数组. "[I"作为JNI类描述符 等价于Java int[]声明。FindClass当装载类失败,返回NULL(可能是没找到类或内存不足)。
注意
类描述符,也可以叫做"类签名"。签名的作用:为了准确描述一件事物. Java Vm定义 了类签名,方法签名;其中方法签名是为了支持方法重载。
FindClass 返回 NULL 的原因:
• 提供了错误的类描述符
• 无法在当前ClassLoader上下文中找到类
解决办法:
• 认真检查类描述符是否正确
• 以"/"作为包分隔符,即类描述符的形式为"xxx/xxx/xxx",而非"xxx.xxx.xxx",也
可简单记忆为"/"用在本地形式(或虚拟机)中;"."分隔符,用在 Java(Java Programming Language)环境中;并且类描述符末尾没有".java",如 FindClass("java/lang/String")而非 FindClass("java/lang/String.java")
• 构造ClassLoader,并利用Class.forName(String name, boolean initialize, ClassLoader loader)装载类
其中第三个解决办法比较复杂,涉及到 Java 的双亲委派模型,类与对象相容性判定等问 题,将有专门文章阐述。
然后调用 NewObjectArray 分配一个对象数组。注意,"基本类型数组"这是个整体的概念, 它是一个对象。后面我们要填充它。
注意,DeleteLocalRef 是释放局部对象引用。
*/