Android JNI学习04-AndroidStudio3.6 java 向 C++函数传递数组

链接:https://pan.baidu.com/s/1zB9r5WwuTMIPNMlYl5HlvA 
提取码:5ndl

在MainActivity中添加如下代码

可以发现,报红色,AndroidStudio希望我们继续创建sendIntArrayToJNI()的C++函数。

快捷生成对应的C++函数

鼠标放到红色上面:alt + enter

生成的C++函数如下

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_jnistudy_MainActivity_sendIntArrayToJNI(JNIEnv *env, jobject thiz,
                                                         jintArray int_array) {
    // TODO: implement sendIntArrayToJNI()
}

这里对这部分代码再次说明下。

JNIEXPORT

这是一个固定的标识,表示当前这个函数可以被JNI框架调用

jstring

这是JNI的返回值的类型,这个类型和java的sendIntArrayToJNI返回值类型是对应的,如下

java中的sendIntArrayToJNI返回值类型是String,C++函数中的返回值类型也该是String,唯一区别是,在JNI里,String 是 用 jstring表示的。

假如,java中的sendIntArrayToJNI返回值类型是int,那么JNIEXPORT 后面就是jint ,在java里的每一个数据类型,在jni中都会有一个数据类型对应,如下是java和JNI 数据类型的对应表

JNICALL

这个是用于指定,C++函数中形参值的入栈顺序。以当前JNI函数sendIntArrayToJNI()为例,它有如下3个参数

这个函数的形参值入栈顺序有2种,一种是从右向左,一种是从左向右。

如何理解呢?

从右向左:就是JNI在调用sendIntArrayToJNI()时,会将传递给sendIntArrayToJNI()的形参值,先保存到栈里,保存的顺序就是从右开始,也就是从右边开始,依次将形参值,存放到栈里,sendIntArrayToJNI()在执行的时候,自己去这个栈里,按照顺序,自己去寻找对应的形参值。

从左向右:就是将形参值,从左边开始,依次存放到栈里。

这是一个固定的写法,各位采用默认的方式就行了。默认是从右向左将形参值放到栈里。

JNI函数的形参

生成的JNI函数,有3个形参

有2个是固定的,每个创建的JNI函数都会有,另一个参数是我们在java层定义的。

env

的值是JVM传递过来的,它代表的是当前JVM环境,它提供了很多功能的函数调用,具体后面再说。

thiz

代表的是JNI函数对应的java函数所在的类对象,有点绕扣,比如sendIntArrayToJNI()在MainActivity中定义的,那么这个

thiz就代表MainActivity这个对象

int_array

代表的就是java层sendIntArrayToJNI()的int[]

说了这么多,下面开始获取java传递过来的int[]

先在MainActivity中,添加如下代码

在JNI函数中获取传递过来的数组数据

1.获取数组指针的首地址

jintArray是一个class,它里面并没有提供任何方法,能够直接获取到数组中的元素,因此我们只能通过

env->GetIntArrayElements()来获取jintArray中所保存的数组元素的首地址。只要找到了首地址,我们就能以指针的形式,遍历数组了。

2.以指针的方式遍历数组

代码如下

想要遍历,首先就得获取数组的长度,env->GetArrayLength()就能获取到数组的长度。

现在基本已经完成了遍历的功能,现在我们来把结果输出来,验证下。

日志工具

在jni中,想要将结果打印出来,直接用print,肯定是不行的,需要用JNI中自带的日志函数

__android_log_print

使用这个函数,先要导入头文件

#include <android/log.h>

示例代码如下

这里说明下,__android_log_print 的形参

第一个参数:是日志的优先级,类似于Logcat中的日志级别

第二个参数,是日志的Tag,像java中的Log.e("JNI",“msg”)

第三个参数,就是具体要输出的内容,里面可以使用占位符

第四个参数:就是替换第三个参数中的占位符。

由于这个JNI函数,还有一个返回值,我们就随便返回一个内容吧

完整代码如下

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_jnistudy_MainActivity_sendIntArrayToJNI(JNIEnv *env, jobject thiz,
        jintArray int_array) {
    jint *javaArray = env->GetIntArrayElements(int_array, NULL);

    int32_t length = env->GetArrayLength(int_array);
    for (int k = 0; k < length; ++k) {
        int tmp = *(javaArray+k);
        __android_log_print(ANDROID_LOG_ERROR,"JNI","数组的值:%d",tmp);
    }

    std::string hello = "测试数组传递";
    return env->NewStringUTF(hello.c_str());
}

现在程序就写好了,接下来就运行下吧

Android JNI学习05-AndroidStudio3.6 java 向 JNI函数传递字符串数组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值