jna回调java非常简单,那么jni是如何回调java的?
刚开始接触jni的时候比较懵逼,语法感觉很繁琐,其使用DLL的步骤还是相对比较麻烦,不但涉及到Java编程,还涉及到C/C++编程,可以说JNI是Java的一大弱点!建议大家采用jna。jni毕竟也是java其中的一部分,研究底层写法对大家也是有帮助的,所以本人抽空研究了下,收获颇深,不废话,直接上代码
1、c++ 写法
JavaVM *jvm;
jclass jcls;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
jvm = vm;
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_8) != JNI_OK) {
return JNI_ERR;
}
jcls = (jclass)env->NewGlobalRef(env->FindClass("com/test/voice/input/component/DeviceListener");
return JNI_VERSION_1_8;
}
void callBackJava(int code) {
JNIEnv *env;
jvm->AttachCurrentThread(reinterpret_cast<void **>(&env), nullptr);
jmethodID jconstruct = env->GetMethodID(jcls, "<init>", "()V");
jobject jobj = env->NewObject(jcls, jconstruct);
jmethodID jmethodId = env->GetMethodID(jcls, "dllCallBack", "(I)V");
env->CallVoidMethod(jobj, jmethodId, code);
env->DeleteLocalRef(jobj);
jvm->DetachCurrentThread();
}
JNI_OnLoad方法会在java处调用system.load后调用,主要功能:
(1)保存jvm对象,方便在任意处可以随时获取JNIEnv,
(2)保存回调jclass 对象,本人亲自试过,如果不在这里保存,现用现获取,程序会异常崩溃掉
callBackJava方法回调java的dllCallBack方法,参数int,函数值无返回值。此方法可以在你想要回调java的地方调用
2、java写法
package com.test.voice.input.component;
public class DeviceListener {
private void dllCallBack(int code) {
System.out.println("接收到回调");
}
}
java的包名要与c++上边env->FindClass(“com/test/voice/input/component/DeviceListener”)里边的保持一致
备注:
jni调用dll参考:
https://blog.csdn.net/little__SuperMan/article/details/89283004