美文网首页Android-NDK/JNI
Android NDK开发:C创建Java层的对象

Android NDK开发:C创建Java层的对象

作者: itfitness | 来源:发表于2021-02-12 18:43 被阅读0次

    目录

    相关文章

    Android NDK开发:java调用dll动态链接库方法
    Android NDK开发:JNIEnv的原理
    Android NDK开发:C修改Java的属性
    Android NDK开发:C调用Java层方法

    C创建Java层的对象

    1.根据class对象创建
    这种创建方式需要Java层传递calss对象给C语言层,具体如下:
    Java代码

    public static native NdkDemo createJavaObj(Class clazz);
    

    C语言代码

    JNIEXPORT jobject JNICALL Java_com_itfitness_NdkDemo_createJavaObj
    (JNIEnv* env, jclass jclazz, jclass create_jcalzz) {
    
        char* method_name = "<init>";
        char* method_sign = "()V";
        //构造方法
        jmethodID constructor_method_id = (*env)->GetMethodID(env,create_jcalzz,method_name,method_sign);
    
        //创建对象
        jobject jobj = (*env)->NewObject(env,create_jcalzz, constructor_method_id);
    
        //获取对象的printStr方法
        jmethodID print_method_id = (*env)->GetMethodID(env, create_jcalzz, "printStr", "(Ljava/lang/String;)V");
    
        //创建jstring类型的参数
        jstring param = getJstring(env,"我是C语言传过来的打印参数", "GB2312");
    
        //调用对象的printStr方法
        (*env)->CallVoidMethod(env,jobj, print_method_id,param);
    
        return jobj;
    }
    

    其中getJstring方法也是我在网上找的方法,主要是因为用NewStringUTF方法生成的字符串在idea的控制台乱码,getJstring方法如下:

    jstring getJstring(JNIEnv* env, const char* pat, const char* encod)
    {
        //定义java String类 strClass
        jclass strClass = (*env)->FindClass(env, "Ljava/lang/String;");
    
        //获取java String类方法String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
        jmethodID ctorID = (*env)->GetMethodID(env, strClass, "<init>", "([BLjava/lang/String;)V");
    
        //建立byte数组
        jbyteArray bytes = (*env)->NewByteArray(env, strlen(pat));
    
        //将char* 转换为byte数组
        (*env)->SetByteArrayRegion(env, bytes, 0, strlen(pat), (jbyte*)pat);
    
        // 设置String, 保存语言类型,用于byte数组转换至String时的参数
        jstring encoding = (*env)->NewStringUTF(env, encod); 
    
        //将byte数组转换为java String,并输出
        return (jstring)(*env)->NewObject(env, strClass, ctorID, bytes, encoding);
    }
    

    执行结果如下


    2.根据类的签名创建
    这种方法是先根据类的签名来获取class对象,后面的步骤跟上面的都一样,具体如下:
    Java代码

    public static native NdkDemo createNdkDemoObj();
    

    C语言代码

    JNIEXPORT jobject JNICALL Java_com_itfitness_NdkDemo_createNdkDemoObj
    (JNIEnv* env, jclass jclazz) {
    
        //找到class对象
        jclass ndkdemo_clazz = (*env)->FindClass(env, "Lcom/itfitness/NdkDemo;");
    
        char* method_name = "<init>";
        char* method_sign = "()V";
        //构造方法
        jmethodID constructor_method_id = (*env)->GetMethodID(env, ndkdemo_clazz, method_name, method_sign);
    
        //创建对象
        jobject jobj = (*env)->NewObject(env, ndkdemo_clazz, constructor_method_id);
    
        //获取对象的printStr方法
        jmethodID print_method_id = (*env)->GetMethodID(env, ndkdemo_clazz, "printStr", "(Ljava/lang/String;)V");
    
        //创建jstring类型的参数
        jstring param = getJstring(env, "我是C语言通过类的签名创建的对象", "GB2312");
    
        //调用对象的printStr方法
        (*env)->CallVoidMethod(env, jobj, print_method_id, param);
    
        return jobj;
    }
    

    执行结果如下


    相关文章

      网友评论

        本文标题:Android NDK开发:C创建Java层的对象

        本文链接:https://www.haomeiwen.com/subject/ehqjxltx.html