在使用JNI的过程中,大多数情况可能都是Java调用本地语言,但不可避免的也会碰到本地语言中调用Java中方法的情况。这就碰到了回调的问题,做了小研究特此记录下来。
这里要讲到的回调的例子,是基于上一篇《初始JNI》,增加了回调。
1、定义回调方法
|
|
2、本地语言中调用Java方法
在C++的源码文件中按照步骤来找到Java中的对应的方法并调用。
1)获取Java中的目标类
- 根据类名获取
JNIEnv中的FindClass方法可以根据方法名直接得到Java中的类 - 根据类对象获取
JNIEnv中同样提供了根据Java类的对象来获取Java类的方法,GetObjectClass。
2)获取要调用Java中的方法
此处的获取目标方法,会需要用到方法的标识,即方法名和方法签名(参数和返回值)。
3)执行目标方法
&esmp; 在执行目标方法的时候要注意,如果方法有参数需要传入,应该特别注意进行类型和编码的转换。
执行回调的c++源码如下:
|
|
3、触发本地代码中的回调方法
此处有多种选择,毕竟C++执行Java回调的方法在任何地方都可以调用,此例子中我在Java中定义了一个测试方法来触发。
Java中调用test1来触发此回调函数。
|
|
4、执行回调
运行此程序,得到下图的结果。
可以看到C++中的代码正确的调用了Java中的方法,并传递了参数到Java中。
备注
查看方法签名
JDK中本身提供了查看签名的方法。
|
|
可以很清晰的看到receiveCPPTest方法的签名是
|
|
参数是String类型,返回值是void。
jstring和string
因为Java和C++中数据类型的区别,所以需要进行转换。上面例子中已经写好了一个,代码贴出来。
头文件StringUtils.h
|
|
源码文件StringUtils.cpp
|
|
总结
其实,JNI也没有太难,只是需要注意的细节挺多的,再加上需要同时了解本地语言,所以可能一定程度增加了点难度(对于不懂本地语言的童鞋),总体来说还算简洁。