jni回调java

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
假设我们要在 C++ 中定义一个回调函数 `onEvent`,并且在 Java 中实现一个回调接口 `MyCallback`,我们可以通过以下步骤实现 C++ 回调方法通过 JNI 反射调用 Java 回调方法: 1. 在 C++ 中定义回调函数 `onEvent`,并通过 JNI 将其注册到 Java 中: ```c++ class MyNativeClass { public: typedef void (*CallbackFunc)(int code); static void setCallback(JNIEnv* env, jobject obj, jobject callback) { jclass cls = env->GetObjectClass(callback); if (cls == NULL) return; jmethodID method = env->GetMethodID(cls, "onEvent", "(I)V"); if (method == NULL) return; callbackFunc_ = reinterpret_cast<CallbackFunc>(method); env->DeleteLocalRef(cls); callbackObj_ = env->NewGlobalRef(callback); } static void onEvent(int code) { if (callbackFunc_ != NULL && callbackObj_ != NULL) { JNIEnv* env = getJNIEnv(); env->CallVoidMethod(callbackObj_, reinterpret_cast<jmethodID>(callbackFunc_), code); } } private: static CallbackFunc callbackFunc_; static jobject callbackObj_; }; MyNativeClass::CallbackFunc MyNativeClass::callbackFunc_ = NULL; jobject MyNativeClass::callbackObj_ = NULL; extern "C" JNIEXPORT void JNICALL Java_com_example_MyClass_setCallback(JNIEnv* env, jobject obj, jobject callback) { MyNativeClass::setCallback(env, obj, callback); } ``` 2. 在 Java 中定义回调接口 `MyCallback`: ```java public interface MyCallback { void onEvent(int code); } ``` 3. 在 Java 中实现一个类 `MyClass`,并将 C++ 回调函数注册到该类中: ```java public class MyClass { static { System.loadLibrary("mylibrary"); } private static native void setCallback(MyCallback callback); public void doSomething() { // 调用 C++ 中的 onEvent 函数,触发回调 MyNativeClass.onEvent(0); } } ``` 4. 在 Java 中实现 `MyCallback` 接口并注册到 `MyClass` 中: ```java public class MyCallbackImpl implements MyCallback { @Override public void onEvent(int code) { // 处理回调事件 } } MyClass myObject = new MyClass(); myObject.setCallback(new MyCallbackImpl()); ``` 这样,当 C++ 中调用 `onEvent` 函数时,就会触发 Java 中实现的 `onEvent` 方法,从而实现了 C++ 回调方法通过 JNI 反射调用 Java 回调方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值