链接:https://pan.baidu.com/s/1zB9r5WwuTMIPNMlYl5HlvA
提取码:5ndl
来实现一个功能
java将字符串数组传递给JNI函数,在JNI函数将获取到的数组用日志输出
首先在MainActivity中,添加如下代码
创建对应的JNI函数
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_jnistudy_MainActivity_sendStringArrayToJNI(JNIEnv *env, jobject thiz,
jobjectArray string_array) {
}
获取数组内容,并打印
Java_com_example_jnistudy_MainActivity_sendStringArrayToJNI(JNIEnv *env, jobject thiz,
jobjectArray string_array) {
jint strlength = env->GetArrayLength(string_array);
for (int i = 0; i < strlength; ++i) {
jstring str = static_cast<jstring>(env->GetObjectArrayElement(string_array, i));
const char* s = env->GetStringUTFChars(str,NULL);
LOGE("获取java的参数:%s",s);
}
}
对上面代码做个解释
要遍历一个数组,首先就得获取数组的长度,代码如下
获取单个数组元素,代码如下
env->GetObjectArrayElement(string_array, i)
将jobject转化为jstring
由于GetObjectArrayElement的返回值类型是jobject,而jobject类型是jstring的父类类型,在后面我们要通过GetStringUTFChars获取字符串的首地址,GetStringUTFChars的第一个参数类型要求是jstring,所以此处,要将jobject转化为jstring,具体转化的动作,我们可通过static_cast来转化,具体代码如下
jstring str = static_cast<jstring>(env->GetObjectArrayElement(string_array, i));
获取字符串的首地址
在C/C++语言里,我们要打印一个字符串,首先我们就得知道这个字符串的首地址,env->GetStringUTFChars通过jstring就可以获取字符串的首地址,代码如下
const char* s = env->GetStringUTFChars(str,NULL);
简化日志输出
之前说过,想要看到输出内容,只能用JNI自带的__android_log_print 函数,由于它写的时候,太长了,为了写时方便点,我将__android_log_print定义成了一个宏,代码如下
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,"JNI",__VA_ARGS__);
在代码中,你可以按如下方式使用
LOGE("获取java的参数:%s",s);
完整代码如下
Java_com_example_jnistudy_MainActivity_sendStringArrayToJNI(JNIEnv *env, jobject thiz,
jobjectArray string_array) {
jint strlength = env->GetArrayLength(string_array);
for (int i = 0; i < strlength; ++i) {
jstring str = static_cast<jstring>(env->GetObjectArrayElement(string_array, i));
const char* s = env->GetStringUTFChars(str,NULL);
LOGE("获取java的参数:%s",s);
env->ReleaseStringUTFChars(str,s);
}
std::string hello = "测试字符串数组传递";
return env->NewStringUTF(hello.c_str());
}
那么好,代码写完了,也分析完了,下面可以来看一下具体的运行效果。
在MainActivity中添加如下代码
运行结果如下
释放JNI数组内存空间
如果你用完一个数组后,想要立即释放,通过ReleaseStringUTFChars即可实现