C调用Java的各种情况:
C调用Java代码利用反射进行调用,jni.h中提供相应API,直接调用API进行调用。调用基本步骤如下:
- 得到需要调用的类的字节码
- 得到方法的ID
得到方法ID的时候调用GetMethodID(env, jclass1, "add_number", "(II)I");这个方法的最后一个参数是方法签名,对方法签名其实是对字节码进行签名,所以需要先在Java类中写好方法,然后rebuild project,再进入build\intermediates\classes\debug目录下,打开doc窗口执行‘javap -s + 全类名’ 命令,如“javap -s com.picovr.javacall.NativeMethord”:
- 实例化该类得到该类的对象
- 调用该方法
Java代码:
package com.picovr.javacall; import android.util.Log; /** * Created by PICO-USER on 2017/1/18. */ public class NativeMethord { static { System.loadLibrary("native_jni"); } public void helloFromJava() { Log.i("NativeMethord", "helloFromJava"); } public int add_number(int x, int y) { Log.i("NativeMethord", "add_number add :" + x + " y:" + y); return x + y; } }
C代码:
/* *调用Java中的add_number方法,对20和30进行加法运算 */ JNIEXPORT jint JNICALL Java_com_picovr_javacall_NativeMethord_addNumberCallback (JNIEnv *env, jobject jobj) { //1.得到字节码 //jclass (*FindClass)(JNIEnv*, const char*); jclass jclass1 = (*env)->FindClass(env, "com/picovr/javacall/NativeMethord"); //2.得到方法ID //jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); jmethodID jmethodID1 = (*env)->GetMethodID(env, jclass1, "add_number", "(II)I");//倒数第一个参数:方法签名,倒数第二个参数:方法名 //3.实例化类 //jobject (*AllocObject)(JNIEnv*, jclass); jobject jobject1 = (*env)->AllocObject(env, jclass1); //调用方法 //jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); jint result = (*env)->CallIntMethod(env, jobject1, jmethodID1, 20, 30); LogI("result :%d", result); } /* *调用java中的helloFromJava方法 */ JNIEXPORT jint JNICALL Java_com_picovr_javacall_NativeMethord_getStringCallback (JNIEnv *env, jobject jobj) { //1.得到字节码 //jclass (*FindClass)(JNIEnv*, const char*); jclass jclass1 = (*env)->FindClass(env, "com/picovr/javacall/NativeMethord"); //2.得到方法ID //jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); jmethodID jmethodID1 = (*env)->GetMethodID(env, jclass1, "helloFromJava", "()V");//倒数第一个参数:方法签名,倒数第二个参数:方法名 //3.实例化类 //jobject (*AllocObject)(JNIEnv*, jclass); jobject jobject1 = (*env)->AllocObject(env, jclass1); //调用方法 //jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); (*env)->CallVoidMethod(env, jobject1, jmethodID1); LogI("Java_com_picovr_javacall_NativeMethord_getStringCallback"); }