美文网首页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