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);
}
0 条评论