[JNI]java layer transfer byte[][] to jni layer

java layers:

public class ANIM{
    public byte[][] mAnim;
}
ANIM anim = new ANIM();
anim.mAnim = new byte[2][];
anim.mAnim[0] = new byte[512];
anim.mAnim[0][0] = 1;
anim.mAnim[1] = new byte[512];
anim.mAnim[1][0] = 2;

jni layers:

struct ANIM{
    char** pAnim;
    int iAnimNum;
}

JNIEXPORT jint JNICALL native_Anim_Init(JNIEnv *env, jobject obj, jlong eng, jobject animObj)
{
    int res = MOK;

    ANIM anim = {0};
    jobjectArray animObjectArray = Null;
    jbyteArray* animByteArray = Null;
    jbyte** animByte = Null;
    {
        jclass   animClass     = env->GetObjectClass(animObj);
        jfieldID animField   = env->GetFieldID(animClass, "mAnim", "[[B");
        
        {
            //get jobjectArray from java byte[][]
            animObjectArray = (jobjectArray)env->GetObjectField(animObj, animField);
            if(Null == animObjectArray)
            {
                return -1;
            }
            anim.iAnimNum = env->GetArrayLength(animBufArr);

            //malloc c buffer:
            //anim.pAnim
            anim.pAnim = (char**)malloc(Null, sizeof(char*) * anim.iAnimNum);
            if (Null == anim.pAnim)
            {
                return -1;
            }
            memset(anim.pAnim,0,sizeof(char*) * anim.iAnimNum);

            //malloc jni buffer:
            //animByteArray&animByte
            animByteArray = (jbyteArray*)malloc(Null, sizeof(jbyteArray) * anim.iAnimNum);
            if(Null == animByteArray){
                return -1;
            }
            memset(animByteArray,0,sizeof(jbyteArray)*(anim.iAnimNum));
            /*
            *注意:
            *jbyteArray* animByteArray = Null;
            *animByteArray对应的buffer是在jni层malloc,animByteArray[i]对应的buffer是在java层new好的,即byte[i].
            *所以,jni层需要处理animByteArray的malloc和free;animByteArray[i]内存的创建在java层,释放由JVM管理.
            */

            animByte = (jbyte**)malloc(Null, sizeof(jbyte*)*anim.iAnimNum);
            if(Null == animByte){
                return -1;
            }
            memset(animByte,0,sizeof(jbyte*)*(anim.iAnimNum));

            for(int i=0;i<anim.iAnimNum;i++){
                //从jobjectArray中获取jbyteArray:
                animByteArray[i] = (jbyteArray)env->GetObjectArrayElement(animObjectArray,i);
                int cols = env->GetArrayLength(animByteArray[i]);
                LOGD("cols:%d",cols);
                //从jbyteArray中获取byte基本元素数组的指针,绑定animByteArray[i]和animByte[i]:
                animByte[i] = (jbyte*) env->GetByteArrayElements(animByteArray[i], 0);
                anim.pAnim[i] = (char*)animByte[i];
                LOGD("pAnim i:%d [0]:%d",i,anim.pAnim[i][0]);
            }
        }
    }

    
    //free c:
    //(1)free anim.pAnim
    if (Null != anim.pAnim)
    {
        free(anim.pAnim);
        anim.pAnim = Null;
    }
    //(2)anim.pAnim[i]是java层new的内存,由JVM管理

    //free jni:
    //(1)deleteLocalRef animObjectArray
    if(Null != animObjectArray){
        env->DeleteLocalRef(animObjectArray);
    }
    //(2)free animByteArray&animByte 
    if (Null != animByteArray && Null != animByte)
    {
        for(int i=0;i<anim.iAnimNum;i++){
            LOGD("free animByteArray[i]&animByte[i], i = %d", i);
            if(Null != animByteArray[i] && Null != animByte[i]){
                //与GetByteArrayElements对应,解绑animByteArray[i]和animByte[i]
                env->ReleaseByteArrayElements(animByteArray[i], animByte[i], 0);
                env->DeleteLocalRef(animByteArray[i]);
            }
        }
        //free animByteArray
        if (Null != animByteArray)
        {
            free(animByteArray);
            animByteArray = Null;
        }
        //free animByte
        if (Null != animByte)
        {
            free(animByte);
            animByte = Null;
        }
    }

    return res;
}

 

Guess you like

Origin blog.csdn.net/u012906122/article/details/103851719