https://www.jianshu.com/p/4893848a3249

上面这篇文章已经讲解的十分清楚了,我再补充总结一下。

1.C调用Java的基本步骤

其实和Java中的反射调用差不多,只是传递的参数可能不太一样。

//第一步:获取字节码
jclass jclazz = env->FindClass("JavaNative方法所在类全路径名");
//第二步:获取方法ID
 jmethodID methodID =env->GetMethodID(jclazz, "java方法名", "方法签名");
//第三步:执行方法
env->CallXxxMethod(object,methodID);

JavaNative方法所在类全路径名:注意是/分隔的,不是.分隔的,如:"com/example/jni01/MainActivity"

方法签名:这个其实有规则可以人为地写出来,但是上文中作者给出了一个简便的办法,通过“javap -s 类全路径名”即可获得类中所有方法的签名。(进入到app/build下的classes文件夹,不同版本的as可能路径稍微不同)
详情可参照:
https://blog.csdn.net/lizhiguo0532/article/details/7219357

CallXxxMethod:这里根据Java方法返回的类型不同,需要调用不同的方法。如Void、Int、StaticVoid等。

2.C调用Java示例

1)C调用java空方法

Java:

 //C调用java空方法
    private void helloFromJava(){
        Toast.makeText(this, "C调用了java的空方法",Toast.LENGTH_SHORT ).show();}

 //触发C调用java空方法    public native void callbackmethod();

C:

/**C函数反射调用java中的空方法 */
extern "C" JNIEXPORT void JNICALL Java_com_example_jni01_MainActivity_callbackmethod
        (JNIEnv * env, jobject object){
    jclass jclazz = env->FindClass("com/example/jni01/MainActivity");
    jmethodID methodID =env->GetMethodID(jclazz, "helloFromJava", "()V");
    env->CallVoidMethod(object,methodID);
}

2)C调用java中的带两个int参数的方法

Java:

//C调用java中的带两个int参数的方法
    private int add(int x,int y) {
        return x+y;
    }
//触发C调用java中的带两个int参数的方法
    public native void callbackIntmethod();

C:

/**
 调用java中Int方法
 */
extern "C" JNIEXPORT void JNICALL Java_com_example_jni01_MainActivity_callbackIntmethod
        (JNIEnv * env, jobject object){
    jclass clzz= env->FindClass("com/example/jni01/MainActivity");
    jmethodID methodID= env->GetMethodID(clzz,"add","(II)I");
    int result=env->CallIntMethod(object,methodID,3,4);
    //logcat 打印相加返回的结果
    LOGD("RESLUT = %d",result);
}

3.C调用java中参数为string的方法

Java:

 //C调用java中参数为string的方法
    private void printString(String s){
        Toast.makeText(this, s, Toast.LENGTH_SHORT).show();}
//触发C调用java中参数为string的方法
    public native void callbackStringmethod();

C:

/**
调用java中String方法
*/
extern "C"  JNIEXPORT void JNICALL Java_com_example_jni01_MainActivity_callbackStringmethod
        (JNIEnv * env, jobject object){
    //先获取字节码对象  jclass      (*FindClass)(JNIEnv*, const char*);
    jclass clzz= env->FindClass("com/example/jni01/MainActivity");
    //获取method对象   jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID methodID=env->GetMethodID(clzz,"printString","(Ljava/lang/String;)V");
    //将要传递的字符串先转换成jstring类型 ,然后在传递给java方法
    jstring result=env->NewStringUTF("hello form C/C++ ");
    env->CallVoidMethod(object,methodID,result);
}

4.C调用java中静态方法

Java:

 //C调用java中静态方法
    private static void staticmethod(String s){
        Log.w("毛麒添",s+",我是被C调用的静态方法");
    }
 //触发C调用java中静态方法
    public native void callStaticmethod();

C:

/**
调用Java中的静态方法
 */
extern "C" JNIEXPORT void JNICALL Java_com_example_jni01_MainActivity_callStaticmethod
        (JNIEnv * env, jobject){
    jclass clzz=env->FindClass("com/example/jni01/MainActivity");
    jmethodID methodID= env->GetStaticMethodID(clzz,"staticmethod","(Ljava/lang/String;)V");
    jstring str = env->NewStringUTF("C调用java");
    env->CallStaticVoidMethod(clzz,methodID,str);
}
分类: JNI

0 条评论

发表回复

您的电子邮箱地址不会被公开。