JNI: C/C++调用Java方法

C/C++调用Java方法步骤:

  • FindClass: 可以在C/C++层找到Java层的类
  • GetMethodID/GetFieldID :得到Java层中所有的类/属性
  • NewObject:创建对象,这个对象就代表内存中一个Java对象。有了这个对象之后,再通过GetMethodID/GetFieldId取到的MethodID(其实它就是个索引值)/FieldID,类中这个方法/属性的索引值,到我们创建的一个具体的对象中找它的方法。
  • 上面3步就可以找到具体的方法了。CallMethod/[G/S]etField就是执行这个具体的方法了。其中的Type就是方法的返回值。比如在java层定义了一个返回整型的方法,那么实际调用的具体的函数就是CallMethod。

实际简单操作:

新建一个工程。创建方法不再赘述。只是本例子用了kotlin。

demo模板代码如下:

JNI: C/C++调用Java方法_第1张图片

没啥区别和之前的。

创建一个美眉的类:

JNI: C/C++调用Java方法_第2张图片

然后在c层按步骤编写c层代码:

#include 
#include 


#define  JNI_CLASS_PATH "com/yinlei/ccalljava/Meimei"
extern "C"
JNIEXPORT jstring JNICALL
Java_com_yinlei_ccalljava_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {

    //步骤1:
    jclass  clazz = env->FindClass(JNI_CLASS_PATH);

    //步骤2:是java的构造函数名,这个有点特殊。在我的一篇文章jetpack中的问题中碰见过它。
    //构造函数没输入输出参数,所以这里的signature填写为()V
    jmethodID method_init_id = env->GetMethodID(clazz,"","()V");//拿到构造方法
    jmethodID method_set_id = env->GetMethodID(clazz,"setYear","(I)V");//拿到构造方法
    jmethodID method_get_id = env->GetMethodID(clazz,"getYear","()I");//拿到构造方法

    //步骤3:
    //创建了Meimei对象
    jobject  obj = env->NewObject(clazz,method_init_id);

    //步骤4:调用相应的方法
    env->CallVoidMethod(obj,method_set_id,21);//set函数没返回值
    int year = env->CallIntMethod(obj,method_get_id);//getYear有返回值

    char tmp[] = {0,};
    sprintf(tmp,"%d",year);

    std::string hello = "Hello,";
    hello.append(tmp);
    return env->NewStringUTF(hello.c_str());
}

 

你可能感兴趣的:(Android,JNI)