JNI 中实现类似 C++ 回调方法 - 结构体操作
上篇文章讲述了 JNI 中 C++简单的调用 Java 函数,接下来我们要解决上次留下的疑惑问题进行解答,如何调用带有结构体的 java 函数。
假设:C++要给 Java 传入一个叫做 DataSt 的结构体,那么,Android 也需要定义同样的结构体,保持与 so 文件中的结构体名称以及字段保持一致,否则查询不到。
结构体内容如下:
C++传入的数据保存在:std::vector<DataSt> m_vetArray 中,在 java 中是如何接收带有 STL 的结构体数据呢?
接下来我会逐步进行讲解~
调用讲解
1:定义 Java 结构体
为了让 java 代码中获取到 C++调用的数据时,此时 JAVA 中需要定义这样一个 DataSt 的结构体。
查询 JAVA 中定义结构体的位置
注意:此时 FindClass 对应的就是 Java 中定义结构体的程序路径,一定要写全,否则无法查询到!
2:创建一个 java 数组对象
与 C++方法一样,想要把数据存储到容器中,需要定义一个这样的容器,这里需要明确容器的大小,也就是需要传给 JAVA 数据的大小,类似于 C++的数组。
3:设置 JAVA 方法
结构中存在了两种变量类型:string、int
3.1:获取 id 方法 ID
3.2:获取 vetIndex 中一条 int 值的方法 ID
如果这里不知道如何获取方法,可以结合 java 结构体自动生成的函数一一对应。
4:类型转换
想要让 Java 识别 C++的数据,我们就需要对类型进行转换,依据 DataSt 中的两种结构类型进行处理转换
4.1:string -> jstring
假设:string id = "123";
4.2:int 类型
注意:在 jni 中,int 类型是直接可以赋值的,不需要特殊处理
5:遍历方式存储成 java 结构
这里到了我们存储的重点了,上面的内容都是为这一步做的铺垫。
在第二步骤时,我们假设了 C++容器的大小为 10,那么,我们这里依旧用 10 做处理
int nsize = 10;
我们在进行数据存储是,是按照顺序的方式存储,首先我们要定义一个下标方法。
在进行数据存储时,需要用到这个 method_init_Event 参数的
在 C++中插入一条数据时,例如 vector 直接 push_back 方法就可以了,或者也可以使用 insert 方法。
下面,先将存储的大体框架展示出来
以上就是粗略的赋值流程了,针对于 2 操作,我们进行具体的代码展示吧!
5.1:将 id 数据设置到 objmodel 对象中
第一步:string 转成 jstring 类型
第二步:存储到 objmodel 对象中
5.2:将 vetIndex 数据设置到 objmodel 对象中
6:C++调用 Java 函数传递参数
第五步骤中已经将数据存储到结构体中了,那么这里开始实际调用 JAVA 的函数了。
假设,这里被调用的函数名叫做:RecordDataAndroidBack(数组,bool 类型)
代码解析:
出现函数调用错误时,最容易出现的问题就是 JAVA 函数参数的路径写的不对,或者是格式不正确,90%都是在第三个参数上出问题的,而且,有些问题还会跑偏,让你抓狂,让你无处可找!!
到这里,如何调用带有结构体容器的 JAVA 函数已经讲解完成了,小伙伴们尽情的尝试吧!
我是中国好公民 st,一名 C++开发程序媛~
版权声明: 本文为 InfoQ 作者【中国好公民st】的原创文章。
原文链接:【http://xie.infoq.cn/article/0dfe611673e554825f4a0b64c】。文章转载请联系作者。
评论