一、Java调用C++
方法一:手动生成so
1、新建jni.java,书写静态方法load so以及native方法
public class MyJni {
static {
System.loadLibrary("JniTest");
}
public static native String sayWhat();
}
2、将编写好的 .java文件通过javac生成 .class文件
package jni.test.com.testjni;
public class MyJni {
public MyJni() {
}
public static native String sayWhat();
static {
System.loadLibrary("JniTest");
}
}
3、在上一级目录将 .class文件通过javah生成 .h文件
#include <jni.h>
/* Header for class jni_test_com_testjni_MyJni */
#ifndef _Included_jni_test_com_testjni_MyJni
#define _Included_jni_test_com_testjni_MyJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jni_test_com_testjni_MyJni
* Method: sayWhat
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_jni_test_com_testjni_MyJni_sayWhat
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
4、新建jni文件夹,copy .h文件到新建的 .c文件
5、修改 .c文件的返回值
#include <jni.h>
/* Header for class jni_test_com_testjni_MyJni */
#ifndef _Included_jni_test_com_testjni_MyJni
#define _Included_jni_test_com_testjni_MyJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jni_test_com_testjni_MyJni
* Method: sayWhat
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_jni_test_com_testjni_MyJni_sayWhat
(JNIEnv *env, jclass jobj){
return (*env)->NewStringUTF(env,"JNT funcation get success");
}
#ifdef __cplusplus
}
#endif
#endif
6、配置NDK、so文件名等
ndk.dir=C\:\\Users\\herb\\AppData\\Local\\Android\\Sdk\\ndk-bundle
sdk.dir=C\:\\Users\\herb\\AppData\\Local\\Android\\Sdk
android.useDeprecatedNdk=true
ndk {
moduleName "JniTest"
ldLibs "log", "z", "m"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
7、rebuild生成so
但是此种方式会报错,说studio3.0以后支持CMake的方式来生成和开发so,所以要自己手写CMake文件,比较麻烦,放弃~
方法二:新建项目时添加C++ support即可
二、C++调用Java
1、通过反射调用,首先在c++中写一个被java调用的方法,把当前java中的类、方法、变量通过反射的方式获取到
2、然后就可以通过c++调用获取到的java方法
3、注意:jni函数中变量的生命周期,如果是一个jclass对象,则需要在c++方法获取jclass变量是做一步转化:g_class = (jclass)(env -> NEWGlobalRef(cls));否则可能引起引用报错