写点什么

JNI 中实现类似 C++ 回调的方法(1)

  • 2022-10-24
    河北
  • 本文字数:1040 字

    阅读完需:约 3 分钟

前些日子刚刚解决了 Java 调用 C++代码的中间键搞定,这不,又有新的功能了,还要在写 so 文件,其实我的内心十分的吐槽,左一个右一个的,直接用 java 写不香吗,搞的 C++程序员还得写个中间键,哎!就当自己多了项技能吧!


今天我们就来讲述下如何 JAVA 在调用 so 文件时,如何实现类似于 C++回调的方法吧!


对于回调,C++程序员应该都不陌生吧!

回调函数就是一个通过函数指针调用的函数。如果你把函数指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数

在纯 C++类中实现回调方法不是很难,那么,在 JNI 中让 Android 调用时,中间出现了回调该怎么使用呢?

C++中回调函数的调用方式

定义一个回调函数

typedef void (*CallBackFun)(int nData1, std::string sData2);
复制代码

定义回调函数

CallBackFun m_pCallBackFun;
复制代码

在使用类中注册该函数

void SetCallOperation(CallBackFun fun){    m_pCallBackFun = fun}
复制代码

上述内容完成后我们就可以使用回调函数传递信息了。

根据 C++中的回调方式,让我们的 Android 程序也能实现类似 C++中的回调。

在 JNI 文件中,定义两个类指针:

JNIEnv *mJni;jobject mJobject;
复制代码

当我们自动生成动态接口函数时,会发现,生成的函数接口中,默认会带有两个参数,第一个参数就是 JNIEnv,第二个参数就是 jobject。其次才是我们函数中有效的参数。

在 Native 中不存在回调的方法,在 JNI 文件中的回调只是 Native 调用 JAVA 函数的方法。

最终的调用形式,如下所示:

jmethodID mid = mJni->GetMethodID(cls, "CallBackFunAndroidBack", "(ILjava/lang/String;)V");
mJni->CallVoidMethod(mJobject, mid, 参数1,参数2);
复制代码

使用上述两句代码就可以让 JAVA 函数接收我们传入的参数了。


在这里需要注意以下几个方面:


1:GetMethodID 中传入的函数名一定与 JAVA 环境中调用的函数名保持一致。

2:书写参数时一定要记得使用 JAVA 自身系统的类时,例如:String 类,必须配备";"否则会出现错误。我在开发过程中写的参数较多,一时之间忘记了最后一个分号。导致 Android 调用总是出现问题,还调试了很长时间。这都是教训呀!

3:在使用 JNI 自带的 CallVoidMethod 时,一定要分情况而言,该函数只能传递返回值为 void 类型的回调

4:回调函数中有多少个参数,JNI 的回调类中必须要写全!


以上就实现了简单的参数回调了,那么对于一些复杂的传参来说,比如:需要给 Android 传入一个类似于 std::vector<结构体> 的数据,该如何进行回调呢?这个功能有一些繁琐,下一篇文章我们进行更新哟~


先尝试下这个简单的功能吧!


我是中国好公民 st,一名 C++开发程序媛~

发布于: 刚刚阅读数: 3
用户头像

书山有路勤为径,学海无涯苦作舟 2022-07-01 加入

擅长语言:C++ 涉及语言:Python

评论

发布
暂无评论
JNI中实现类似C++回调的方法(1)_c++_中国好公民st_InfoQ写作社区