java - 当我构建一个线程来调用 JNI C++ 函数时,程序崩溃了
问题描述
我想在子线程中使用这三个函数,但是程序崩溃了。
这是树 C++ 函数:
//here are three JNI interface
public native byte[] readImage(String str);
public native byte[] FPGAEnhancement(String str, int flag);
public native byte[] FPGASobel(String str, int flag);
这三个函数可以在android程序中正确使用,但是当我建立一个子线程并使用这三个函数时,程序崩溃了。
经测试,似乎这条线崩溃了,结果无法返回。
env->SetByteArrayRegion(jarrRV, 0, length, data);
这是 readImage 函数:
Java_wearablepc_ftcl_hit_edu_cn_fpga_MainActivity_readImage(
JNIEnv *env, jobject, jstring jstr) {
FILE *fp;
fp = fopen(jstringTostring(env, jstr), "rb");
if (fp != NULL) {
int length = getFileLength(fp);
Log_i("fp length");
if(length<=0) {
jbyteArray jarrRV = env->NewByteArray(1);
return jarrRV;
} else {
jbyteArray jarrRV = env->NewByteArray(length);
jbyte data[length];
readImage(fp, data, length);
fclose(fp);
env->SetByteArrayRegion(jarrRV, 0, length, data);
return jarrRV;
}
} else {
jbyteArray jarrRV = env->NewByteArray(1);
return jarrRV;
}
我想我在子线程中调用 C++ 函数的方式可能有问题,但我不知道它到底是什么。谢谢!!
解决方案
当图像文件很大时,在堆栈上分配data[length]可能会耗尽堆栈,并且案例崩溃。你实际上根本不需要这个数组,你可以安全地直接访问新创建的jarrRV的字节:
jbyteArray jarrRV = env->NewByteArray(length);
jboolean isCopy;
jbyte data = env->GetByteArrayElements(env, jarrRV, &isCopy);
readImage(fp, data, length);
fclose(fp);
env->ReleaseByteArrayElements(jarrRV, data, 0);
对您的 C++ 代码的其他一些评论:
- 似乎在某些情况下,文件不会被关闭。
- 在所有情况下,jstringTostring()都可能泄漏本机和 Java 对象。请不要低估这种泄漏在多线程环境中的影响。
推荐阅读
- c# - 具有默认 Polly 策略处理程序注册和使用 SimpleInjector 注入的 HttpClientFactory
- c# - 如何将光线投射到面向方向的玩家?
- jmeter - jmeter 使用 jconn2 而不是 jtds 连接到 sybase16
- r - R 和 RStudio 在 Mac M1 上运行 read_parquet() 时崩溃
- java - 从 Java 到 Kotlin 的反射和调用方法
- javascript - 如何使用 DOM 选择器取消选中复选框?
- jquery - 无法隐藏 jquery FLOT 网格上的垂直线
- jmeter - 压力测试 mqtt 代理(HiveMQ CE 代理)
- python - 具有多个条件的 xlsxwriter 条件格式公式
- hibernate - Hibernate 在我的实体关系上生成太多外部连接