JNI之C代碼訪問java中的成員和java調C

第一章:C調java

第一種:訪問java中的非靜態方法

         

1.jclass clz=(*env)->GetObjectClass(env,jobj)

         //獲取簽名

2.jmethodID mid=(*env)->GetMethodID(env,jclz,"方法名","簽名");

        3.jint num=(*env)->CallIntMethod(env,job,mid,200);

       

第二種:訪問java中的靜態方法

       1.jclass clz=(*env)->GetObjectClass(env,jobj)

         //獲取簽名

       2.jmethodID jmid=(*env)->GetStaticMethodID(env,clz,"方法名",“簽名”);

       3.jstring uuid=(*env)->callStaticObjectMethod(env,clz,jmid)

 

第三種:訪問java中的構造方法

//找到對應的類

        1.jclass   jclz=(*env)->FindClass(env,jobj):

       

2.jmethodID jmid=(*env)->GetMethodID(env,jclz,"<init>","()V");
        //實例化對象 例如
3.jobject date_obj=(*env)->NewObject(env,jclz,jmid);

        //獲取要調用對象中的方法的方法ID

        4.jmethodID time_mid=(*env)->GetMethodID(env,jcld,"getTime","()L");

        //調用方法

        5.jlong time=(*env)->CallLongMethod(env,date_obj,time_mid);

第二章 java調C代碼
    jboolean iscp;
    char* c_str=(*env)->GetStringUTFChar(env,in,&iscp);//回重新開闢一塊內存
    第三個參數說明:作爲返回值。判斷是否開闢內存有效
    if(iscp==JNI_TRUE){
         
    }
    中文字符亂碼處理
char * stringChar(JNIEnv* env){

    char* c_str="上課的時間空間";
    jclass str_cls=(*env)->FindClass(env,"java/lang/String");
    jmethodID jmid=(*env)->GetMethodID(env,str_cls,"<init>","([BLjava/lang/String:)V");

    jbyteArray bytes=(*env)->NewByteArray(env,strlen(c_str));
    // 將字符串從0開始拷貝到bytes中
    (*env)->SetByteArrayRegion(env,bytes,0,strlen(c_str),c_str);

    jstring strencode=(*env)->NewStringUTF(env,"GB2312");

    return (*env)->NewObject(env,str_cls,jmid,bytes,strencode);



}

   對int 數組進行排序
   java    public native int[] giveArray(int[] arr);
   
//引用數據類型的數組
/**
 * 1.create jobject array
 * 2.eva
 * 3.return;
 */
JNIEXPORT jobjectArray JNICALL
Java_mdks_com_mvp_jni_JNITest_initStringArray(JNIEnv *env, jobject jobj, jint size) {

    jobjectArray result;

    jclass jclz;
    jclz=(*env)->FindClass(env,"java/lang/String");
    if (jclz==NULL){

        return NULL;
    }
    result=(*env)->NewObjectArray(env,size,jclz,jobj);
    //eva
    if (result==NULL){

        return NULL;
    }
    for (int i = 0; i < size;i++) {
        char* c_str=(char*)malloc(256);
        memset(c_str,0,256);
        //將int 轉化成爲char
        sprintf(c_str,"hello num:%d\n",i);
        //c->jstring
        jstring str=(*env)->NewStringUTF(env,c_str);
        if (str==NULL){
            return NULL;
        }
        //將jstring 給數組
        (*env)->SetObjectArrayElement(env,result,i,str);
        free(c_str);
        c_str=NULL;
        (*env)->DeleteGlobalRef(env,str);
    }
    // TODO
    return result;
}
   

引用:

//局部引用
//定義方式多樣:FindClass NewObject ,GetObjectClass,NewCharArray....
//NewLocalRef
//釋放方式:1.方法調用完JVM 會自動釋放 2.手動釋放:DeleteLocalRef
//不能在多線程中使用

JNIEXPORT void JNICALL
Java_mdks_com_mvp_jni_JNITest_localRef(JNIEnv *env, jobject instance) {

    int i=0;
    for (int i = 0; i <5 ; ++i) {

        jclass cls=(*env)->FindClass(env,"java/util/Date");

        jmethodID jmid=(*env)->GetMethodID(env,cls,"<init>","()V");
        //創建局部引用
        jobject obj=(*env)->NewObject(env,cls,jmid);
        //使用引用

        //釋放引用
        (*env)->DeleteLocalRef(env,cls);
        (*env)->DeleteLocalRef(env,obj);

    }
    // TODO

}
//全局引用----跨線程,跨方法
jstring global_str;
JNIEXPORT void JNICALL
Java_mdks_com_mvp_jni_JNITest_createGlobalRef(JNIEnv *env, jobject instance) {

    jobject obj=(*env)->NewStringUTF(env,"instance ");
    global_str=(*env)->NewGlobalRef(env,obj);
    // TODO

}

JNIEXPORT jstring JNICALL
Java_mdks_com_mvp_jni_JNITest_getGlobalRef(JNIEnv *env, jobject instance) {

    // TODO
    return global_str;
}

JNIEXPORT void JNICALL
Java_mdks_com_mvp_jni_JNITest_delGlobalRef(JNIEnv *env, jobject instance) {

    // TODO
    (*env)->DeleteGlobalRef(env,global_str);
}


//弱全局引用
//它不會阻止GC,/跨線程,跨方法使用
jclass g_weak_cls;

JNIEXPORT jstring JNICALL
Java_mdks_com_mvp_jni_JNITest_createWeakRef(JNIEnv *env, jobject instance) {

    jclass cls_string=(*env)->FindClass(env,"java/lang/String");
    g_weak_cls=(*env)->NewWeakGlobalRef(env,cls_string);
    // TODO
    return g_weak_cls;
}
異常:
//JNI 異常處理
JNIEXPORT void JNICALL
Java_mdks_com_mvp_jni_JNITest_exception(JNIEnv *env, jobject instance) {

    jclass cls=(*env)->GetObjectClass(env,instance);
    jfieldID fid=(*env)->GetFieldID(env,cls,"kjdslfj","Ljava/lang/String:");

    jthrowable ex=(*env)->ExceptionOccurred(env);
    //判斷異常是否發送
    if(ex!=NULL){
        jclass newExce;
        //清空JNI產生的異常
        (*env)->ExceptionClear(env);
        newExce=(*env)->FindClass(env,"java/lang/IllegalArgumentException");
        if (newExce==NULL){

            printf("exception\n");
            return ;
        }
        (*env)->ThrowNew(env,newExce,"Throw exception from JNI: GetFieldID");
    }
    // TODO
    printf("exception\n");
    
}
//局部靜態變量進行緩存
JNIEXPORT void JNICALL
Java_mdks_com_mvp_jni_JNITest_cached(JNIEnv *env, jobject instance) {

    jclass cls=(*env)->GetObjectClass(env,instance);
    static jfieldID  fid;
    if (fid==NULL){
        fid=(*env)->GetFieldID(env,cls,"key","Ljava/lang/String:");
        printf("GetFieldId\n");
    }
    // TODO
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章