在尝试使用JNI调用java的方法时运行报错
JNI DETECTED ERROR IN APPLICATION
后来发现这个错误基本上是数据类型不匹配的报错
话不多说直接上源码
jni代码
/** * jni 回调测试 callBack */ extern "C" JNIEXPORT void JNICALL Java_com_launch_canjniapplication_MainActivity_callbackStringJNI(JNIEnv *env, jobject instance, jobject callbackUtils) { std::string hello = "WTF Hello from C++"; //获取传入的类 类似反射 jclass clazz = (*env).GetObjectClass(callbackUtils); //获取方法名 //第三个参数 (方法的入参类型)返回类型 (II)V -> void function(int i, int j){} // 对象以"L"开头,以";"结尾,中间是用"/" 隔开的包及类名 如果多个参数 需要用 ; 隔开。 比如 String -> Ljava/lang/String // 详情见 https://blog.csdn.net/qq_27278957/article/details/77164353 jmethodID mid = (*env).GetMethodID(clazz, "printStr", "(Ljava/lang/String;)V"); //如果方法ID没有找到 if (mid == NULL){ __android_log_print(ANDROID_LOG_INFO,"HGY", "method printStr ID not found"); return; } //执行指定方法 env -> CallVoidMethod(callbackUtils, mid, hello.c_str()); return; }
java代码:
public interface CallbackUtils { void printStr(String log); }
调用代码
public native void callbackStringJNI(CallbackUtils callbackUtils);
编译一切都没有问题, 但是到运行的时候报错
JNI DETECTED ERROR IN APPLICATION
后来查资料找报错原因, 基本上是说类型不匹配的问题。
然后在代码里面看到示例的程序里面返回String的代码是
env->NewStringUTF(hello.c_str())
所以将最后执行指定方法的代码修改为
//JNI DETECTED ERROR IN APPLICATION 报错 需要将C/C++中的字符串转换为中间层jstring返回 //是因为回调的时候 java需要的是String类型 对应到JNI里面就是 C的 jstring 所以要做个转换 //hello 是 std::string 类型的 .c_str() 也是转化为了 *char 也不是jstring 还是要做一个转换 jstring callStr = env->NewStringUTF(hello.c_str()); //执行指定方法 env -> CallVoidMethod(callbackUtils, mid, callStr);
运行成功
主要原因还是
std::string 这个类型并不是String类型 而是要先转化为中间类型 jstring
个人愚见 如有问题欢迎指出