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
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值