[问题记录]JNI的整型数组返回出现stack corruption
在项目中编写了一个返回整型数组的JNI代码,但是在测试时发现问题,会产生stack corruption错误,debug之后发现是return的地方出错,故在此记录。本人水平有限,如果理解有错,请多多指教。
1.错误代码
C:
JNIEXPORT jintArray JNICALL
Java_com_example_final2_MainActivity_read_1from_1device(JNIEnv *env, jobject thiz, jint len) {
int n=0,i=0;
char buf[100];
int *buf_int;
buf_int = (int*)malloc(sizeof(int)*len);
int l = len;
if (read(fd_io,buf,l)){
jintArray jntarray = (*env)->NewIntArray(env, len);
jint * jintp = (*env)->GetIntArrayElements(env, jntarray, NULL);
for(i=0;buf[i]!='\0';i++){
buf_int[n++] = buf[i]-'0';
jintp[i] = buf_int[i];
}
free(buf_int);
(*env)->ReleaseIntArrayElements(env, jntarray, jintp, 0);
return jntarray;
}
else{
return 0;
}
这个函数的功能是将从节点中read出的含有一个元素的char数组转为int类型数组再转为jntarray类型数组输出。
JAVA:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
int[] as = read_from_device(1);
System.out.println(Arrays.toString(as));
}
public native int[] read_from_device(int len);
}
但是在执行是出现了堆栈破损错误,同时另一个read很多元素的char数组执行同样的操作并return却不会报错。
原因在没有理解:
(*env)->ReleaseIntArrayElements(env, jntarray, jintp, 0);
这一步操作的意义是,将jintp的值传给jntarray,同时将jintp指针释放,然而,jintp是定义jntarray空间的指针,因此,当只有一个数据将要被传递时,jintp释放时,jntarray所在空间也被销毁。
总而言之,在有(*env)->ReleaseIntArrayElements(env, jntarray, jintp, 0)语句时,不应该return jntarray,会造成错误。
2.修改代码
因此,上述功能的代码可以修改为:
C:
JNIEXPORT jint JNICALL
Java_com_example_final2_MainActivity_final_1read_1return(JNIEnv *env, jobject thiz,
jintArray get_int_array) {
char buf_read[2];
if (read(fd_io,buf_read,1)) {
jint *jintp = (*env)->GetIntArrayElements(env, get_int_array, NULL);
for (int i = 0; buf_read[i] != '\0'; i++) {
jintp[i] = buf_read[i] - '0';
}
(*env)->ReleaseIntArrayElements(env, get_int_array, jintp, 0);
return 1;
}
else return 0;
}
JAVA:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
int[] test_return_array={0};
test_return(test_return_array);
Log.d("return array",Arrays.toString(test_return_array));
for(int i :test_return_array){
System.out.println(i);
}
}
public native int final_read_return(int[] get_int_array);
}
至此解决了所有的问题,而且代码也更加简介规范。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)