【环境配置】Android-Studio-OpenCV-JNI以及常见错误 ( 持续更新 )
最近一个项目要编译深度学习的库,需要用到 opencv 和 JNI,本文档用于记录环境配置中遇到的常见错误以及解决方案
Invalid Gradle JDK configuration found
failed
Invalid Gradle JDK configuration foundInvalid Gradle JDK configuration found. Open Gradle Settings
Change JDK location
解决办法: 删除文件
.idea/gradle.xml
和 .idea/workspace.xml
, 重新编译;
解决办法:Invalid Gradle JDK configuration found
clang++: error: unknown argument: ‘-static-openmp’
原因是NDK版本过高,跟当前的AndroidStudio版本不匹配。选择升级AndroidStudio或者降低NDK版本即可。
重新下载21.3.6528147版本,配置NDK通过,rebuild项目通过,问题解决, 最新版的 Android Studio 降级到 Android Studio 4.2.1 版本,NDK 降级到 21.3.6528147;
问题:clang++.exe: error: unknown argument: ‘-static-openmp‘
NDK版本!clang++: error: unknown argument: ‘-static-openmp‘
Android res\values-v26\values-v26.xml:9:5-12:13: AAPT: error: resource android:attr/colorError not f
解决方法:
compileSdkVersion 设置为28
Android res\values-v26\values-v26.xml:9:5-12:13: AAPT: error: resource android:attr/colorError not f
2 files found with path ‘lib/arm64-v8a/xxx.so‘ 问题
最后在自己的 nativelib module
的 build.gradle
的 android{}
加上
sourceSets {main {jniLibs.srcDirs = ['libs']}}
2 files found with path ‘lib/arm64-v8a/xxx.so‘ 问题
undefined reference to `cv::String::deallocate()一种可能解决方案
解决方案:替换库文件时候,同步替换头文件
undefined reference to `cv::String::deallocate()一种可能解决方案
关于解决gradle版本与gradle插件版本不一致问题的方法之一
关于解决gradle版本与gradle插件版本不一致问题的方法之一
Algorithm HmacPBESHA256 not available
在 D:\Android\sdk\.android
的目录下找到文件 debug.keystore
, 其实不缺少签名文件,这个问题,应该是之前安装了多个版本的 Android Studio,导致签名文件被覆盖了, 删除 debug.keystore
文件,重新签名即可。
JNI GetFieldID和GetMethodID函数解释及方法签名
GetFieldID
是得到java
类中的参数ID
,GetMethodID
得到java
类中方法的ID
,它们只能调用类中声明为public
的参数或方法。
举例说明:
jclass c = (*env)->FindClass(env,"com/camera/webcam/Test");
jfieldID width_id = (*env)->GetFieldID(env, c, "width", "I");
第一个参数:JNI接口对象;第二个参数:Java类对象;第三个参数:参数名(或方法名);第四个参数:该参数(或方法)的签名。
- 方法签名
调用 JNI
的 GetMethodID
函数获取一个 jmethodID
时,需要传入一个方法名称和方法签名,方法名称就是在 Java
中定义的方法名,方法签名的格式为:(形参参数类型列表)返回值。
JNI GetFieldID和GetMethodID函数解释及方法签名
如何从JNI返回多个数组到Java?
当您希望从一个函数返回多个“东西”时,您有两个选项(这并不是 JNI
特有的):要么创建一个包含所有结果的包装器对象(在您的例子中,是一个包含3个数组字段的 Java
类),要么使用 out
参数。也许,在您的情况下,如果您知道调用前的长度,后者可能会更容易一些。
所以,在 Java
中,您可以编写如下内容
package p;public class C {public void f() {byte[] array1 = new byte[10];int[] array2 = new int[20];String[] array3 = new String[5];fillArrays(array1, array2, array3);}native void fillArrays(byte[] byteArray, int[] intArray, String[] stringArray);
}
现在,在 C
中,这看起来是这样的:
JNIEXPORT void JNICALL
Java_p_C_fillArrays(JNIEnv *env, jobject thisC, jbyteArray byteArray, jintArray intArray, jobjectArray stringArray)
{jboolean isCopy;jint i = 0;char* names[] = {"one", "two", "three"};jbyte *c_byteArray = (*env)->GetByteArrayElements(env, byteArray, &isCopy);for (i=0; i<(*env)->GetArrayLength(env, byteArray); i++) {c_byteArray[i] = (jbyte)i;}(*env)->ReleaseByteArrayElements(env, byteArray, c_byteArray, 0);jint *c_intArray = (*env)->GetIntArrayElements(env, intArray, &isCopy);for (i=0; i<(*env)->GetArrayLength(env, intArray); i++) {c_intArray[i] = i;}(*env)->ReleaseIntArrayElements(env, intArray, c_intArray, 0);for (i=0; i<(*env)->GetArrayLength(env, stringArray) && i<sizeof(names)/sizeof(names[0]); i++) {(*env)->SetObjectArrayElement(env, stringArray, i, (*env)->NewStringUTF(env, names[i]));}
}
如何从JNI返回多个数组到Java?
Java: JNI对数组赋值并返回给Java
在 JNI
中对 Java
层的数组赋值有两种方式:一是在 Java
层创建好数组,然后传递到 JNI
层,由 JNI
层进行赋值;二是直接在 JNI
层创建好数组并赋值,然后返回数组到 Java
层。下面是两种方式的对比实现:
创建两个 native
方法
//传递数组,操作后,返回public native void passArrayMethod(int[] arr);//创建指定长度数组public native int[] createArrayMethod(int len);
生成对应的 C
函数
JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_passArrayMethod(JNIEnv *, jobject, jintArray);JNIEXPORT jintArray JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_createArrayMethod(JNIEnv *, jobject, jint);
传递数组给 JNI
,修改第一个元素值,然后排序
int com(const void *a, const void *b){return *(int *)a - *(int *)b;//升序
}
JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_passArrayMethod(JNIEnv *env, jobject jobj, jintArray jarr){//1.获取数组指针jint *arr = env->GetIntArrayElements(jarr, NULL);*arr = 100;//2.获取数组长度int len = env->GetArrayLength(jarr);//3.排序qsort(arr, len, sizeof(jint), com);//4.释放资源env->ReleaseIntArrayElements(jarr, arr, JNI_COMMIT);
// env->ReleaseIntArrayElements(jarr, arr, JNI_ABORT);// 对于最后一个参数(如果指针指向的数组为副本时,否则该参数不起作用)// 0 copy back the content and free the elems buffer// JNI_COMMIT copy back the content but do not free the elems buffer// JNI_ABORT free the buffer without copying back the possible changes
};
JNI
生成数组,并返回
JNIEXPORT jintArray JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_createArrayMethod(JNIEnv *env, jobject jobj, jint len){//1.新建长度len数组jintArray jarr = env->NewIntArray(len);//2.获取数组指针jint *arr = env->GetIntArrayElements(jarr, NULL);//3.赋值int i = 0;for(; i < len; i++){arr[i] = i;}//4.释放资源env->ReleaseIntArrayElements(jarr, arr, 0);//5.返回数组return jarr;
};
MainActivity
中调用
int[] arr = {1, 3, 2, 6, 8, 0};Log.i(TAG, "arr修改前: " + getArrayString(arr));jd.passArrayMethod(arr);Log.i(TAG, "arr修改后: " + getArrayString(arr));Log.i(TAG, "------------------------------------------");int[] arr_new = jd.createArrayMethod(10);Log.i(TAG, "arr_new: "+ getArrayString(arr_new) );
输出结果:
09-26 17:02:29.454 994-994/com.test.git.jnidemo I/MainActivity-: arr修改前: ,1,3,2,6,8,0
09-26 17:02:29.454 994-994/com.test.git.jnidemo I/MainActivity-: arr修改后: ,0,2,3,6,8,100
09-26 17:02:29.454 994-994/com.test.git.jnidemo I/MainActivity-: ------------------------------------------
09-26 17:02:29.454 994-994/com.test.git.jnidemo I/MainActivity-: arr_new: ,0,1,2,3,4,5,6,7,8,9
Java: JNI对数组赋值并返回给Java
[JNI 编程上手指南之 JNIEnv 详解]
- JNIEnv 是什么?
JNIEnv
即 Java Native Interface Environment
,Java
本地编程接口环境。JNIEnv
内部定义了很多函数用于简化我们的 JNI
编程。
JNI
把 Java
中的所有对象或者对象数组当作一个 C
指针传递到本地方法中,这个指针指向 JVM
中的内部数据结构(对象用 jobject
来表示,而对象数组用 jobjectArray
或者具体是基本类型数组),而内部的数据结构在内存中的存储方式是不可见的。只能从 JNIEnv
指针指向的函数表中选择合适的 JNI
函数来操作 JVM
中的数据结构。
在 C
语言中,JNIEnv
是一个指向 JNINativeInterface_
结构体的指针:
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;
#else
typedef const struct JNINativeInterface_ *JNIEnv; // C 语言
#endifstruct JNINativeInterface_ {void *reserved0;void *reserved1;void *reserved2;void *reserved3;jint (JNICALL *GetVersion)(JNIEnv *env);jclass (JNICALL *DefineClass)(JNIEnv *env, const char *name, jobject loader, const jbyte *buf,jsize len);jstring (JNICALL *NewStringUTF)(JNIEnv *env, const char *utf);//省略其他函数指针//......
}
JNINativeInterface_
结构体中定义了非常多的函数指针,这些函数用于简化我们的 JNI
编程。C
语言中,JNIEnv
中函数的使用方式如下:
JNIEnv * env
// env 的实际类型是 JNINativeInterface_**
(*env)->NewStringUTF(env,"Hello from JNI !");
在 C++
代码中,JNIEnv
是一个 JNIEnv_
结构体:
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;
#else
typedef const struct JNINativeInterface_ *JNIEnv;
#endifstruct JNIEnv_ {const struct JNINativeInterface_ *functions;
#ifdef __cplusplusjint GetVersion() {return functions->GetVersion(this);}jclass DefineClass(const char *name, jobject loader, const jbyte *buf,jsize len) {return functions->DefineClass(this, name, loader, buf, len);}jclass FindClass(const char *name) {return functions->FindClass(this, name);}jmethodID FromReflectedMethod(jobject method) {return functions->FromReflectedMethod(this,method);}jfieldID FromReflectedField(jobject field) {return functions->FromReflectedField(this,field);}jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) {return functions->ToReflectedMethod(this, cls, methodID, isStatic);}jclass GetSuperclass(jclass sub) {return functions->GetSuperclass(this, sub);}//省略其他函数//......
}
JNIEnv_
结构体中同样定义了非常多的成员函数,这些函数用于简化我们的 JNI
编程。C++
语言中,JNIEnv
中函数的使用方式如下:
//JNIEnv * env
// env 的实际类型是 JNIEnv_*
env->NewstringUTF ( "Hello from JNI ! ");
更多详情见: JNI 编程上手指南之 JNIEnv 详解
Android NDK开发:JNI实战篇
java调用本地方法–JNI访问List集合
JNI系列(四)JAVA数据类型和JNI类型对照表
【参考】
Android Studio配置OpenCV的JNI接口
【Android+OpenCV】Android Studio的安装全过程+在Android Studio中配置OpenCV-重点关注
NDK开发遇到的三个错误:‘javah’ 不是内部或外部命令,编码GBK的不可映射字符, 程序包XX.XX不存在
OpenCV 在 Android Studio 的使用教程
Android Studio使用OpenCV进行图像基本处理
Android学习笔记之——基于Android的opencv开发(Android studio3.6+opencv4.3.0开发环境搭建)
解决办法:Invalid Gradle JDK configuration found
NDK版本!clang++: error: unknown argument: ‘-static-openmp‘
问题:clang++.exe: error: unknown argument: ‘-static-openmp‘
Android res\values-v26\values-v26.xml:9:5-12:13: AAPT: error: resource android:attr/colorError not f
JNI GetFieldID和GetMethodID函数解释及方法签名
如何从JNI返回多个数组到Java?
Java: JNI对数组赋值并返回给Java
JNI 编程上手指南之 JNIEnv 详解
Android NDK开发:JNI实战篇
java调用本地方法–JNI访问List集合
JNI系列(四)JAVA数据类型和JNI类型对照表
相关文章:

【环境配置】Android-Studio-OpenCV-JNI以及常见错误 ( 持续更新 )
最近一个项目要编译深度学习的库,需要用到 opencv 和 JNI,本文档用于记录环境配置中遇到的常见错误以及解决方案 Invalid Gradle JDK configuration found failed Invalid Gradle JDK configuration foundInvalid Gradle JDK configuration found. Open…...

js 正则表达式 验证 :页面中一个输入框,可输入1个或多个vid/pid,使用英文逗号隔开...
就是意思一个输入框里面,按VID/PID格式输入,VID和PID最大长度是4,最多50组 1、页面代码 <el-form ref"ruleForm" :model"tempSet" :rules"rules" label-position"right"> <!-- 最多 50组,每组9个字符…...

【算法与数据结构】112、LeetCode路径总和
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:本题通过计算根节点到叶子节点路径上节点的值之和,然后再对比目标值。利用文章【算法和数据…...

②matlab桌面和编辑器
目录 matlab编辑器练习 运行脚本 matlab编辑器练习 您可以通过点击灰色代码框在脚本中输入命令。 准备就绪后,您可以通过点击蓝色的提交按钮提交代码。 任务 在脚本中输入命令 r 3。 2.任务 在脚本中添加命令 x pi*r^2。 附加练习 当您在实时编辑器中完成…...

高亮img、pdf重点部分(html2canvas、pdfjs-dist、react-pdf)
可用业务场景 报销单据审批中,高亮发票部分 需求 后台返回一张图片或者pdf、返回一组坐标,坐标类型[number,number,number,number],分别代表了x、y、width、height。需要根据坐标在图片上高亮出来坐标位置。如下图 高亮的坐标是࿱…...

18.神奇导航菜单指示器
效果 源码 <!DOCTYPE html> <html> <head> <title>Magic Menu Indicator | 03</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body><div class="navig…...

WPF+Prism+WebApi 学习总结
一、基本概念 WPF:WPF(Windows Presentation Foundation)是(微软推出的)基于Windows的用户界面框架,提供了统一的编程模型,语言和框架,做到了分离界面设计人员与开发人员的工作;WPF…...

uniapp热更新
首先热更新需要wgt包; 其次先了解这两个组件 下载的方法 安装的组件 场景: 当你项目的js文件或者页面文件或者静态图片文件css文件更新的时候可以走热更新; 而当你安装新的组件插件或者开启新的权限等功能的时候就无法通过热更新进行更新了…...
AUTOSAR从入门到精通-【应用篇】基于CAN协议的汽车尾气后处理诊断系统的软件开发(续)
目录 尾气后处理诊断程序的开发 5.1 数据库的解析 5.1.1 寻找XML文件 5.1.2 读取XML文件...

mybatis plus新版代码生成器,类型转换处理器ITypeConvertHandler使用
目录 引言关键代码源码分析记录一坑类型转换的第二种方式完整源码地址 引言 当默认生成的数据类型不满足时,就需要自定义指定要生成的类型 关键代码 FastAutoGenerator.create(url, username, password).dataSourceConfig(builder -> {builder.typeConvertHandl…...

python中的matplotlib画直方图(数据分析与可视化)
python中的matplotlib画直方图(数据分析与可视化) import numpy as np import pandas as pd import matplotlib.pyplot as pltpd.set_option("max_columns",None) plt.rcParams[font.sans-serif][SimHei] plt.rcParams[axes.unicode_minus]Fa…...

【详解】文本检测OCR模型的评价指标
关于文本检测OCR模型的评价指标 前言:网上关于评价标准乱七八糟的,有关于单词的,有关于段落的,似乎没见过谁解释一下常见论文中常用的评价指标具体是怎么计算的,比如DBNet,比如RCNN,这似乎好像…...
Python遥感图像处理应用篇038 GDAL 遥感图像特征提取(统计特征图)
1.图像统计特征 遥感图像的统计特征是对图像中像素值的统计分布进行定量化描述的过程。这些统计特征可以提供关于图像内容和特性的有用信息。下面是一些常用的遥感图像统计特征描述方法: 平均值(Mean):计算图像中所有像素值的平均值,可以反映整个图像的亮度水平。 方差(…...

全局ID生成方式
全局ID生成方式 目录 1. 全局唯一id介绍 1.1 特点 2. 常见的全局唯一id生成策略 2.1 利用数据库自增字段生成id2.2 UUID2.3 Redis生成id2.4 zookeeper生成ID2.5 Twitter的snowflake算法 3. 面试题目:实现一个全局的ID生成器,注意线程安全 3.1 单例模式…...

c++之指针
总结性质 我们如何在一个函数中获取数组的长度: 我们都知道,在main函数中我们获得数组的长度只需要使用sizeof(a)/sizeof(a【0】)即可获得,但当我们把一个数组传入到方法时,c默认把…...

JVM 访问对象的两种方式
Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。由于 reference 类型在《Java 虚拟机规范》里面只规定了它是一个指向对象的引用,并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置,所以对象访问方式也是由虚拟机实现而…...

yo!这里是Linux基础开发工具介绍
目录 前言 基础开发工具 yum vim 1.基本介绍 2.基本操作 3.正常模式常用命令 4.底行模式常用命令 gcc/g gdb 1.基本介绍 2.常用操作 make/Makefile 1.背景 2.介绍 3.使用 git 1.介绍 2.操作 进度条程序简单实现 后记 前言 在学完初步的基础指令及权限控…...

本地组策略编辑器找不到怎么解决?| 解决windows home 版本隐藏本地组策略编辑器的问题 | 简单的介绍本地组策略编辑器
一般的 Windows 非家庭系统中,本地组策略编辑器不会被隐藏,但在某些特定情况下,可能会受到限制或不可用。如果你无法访问本地组策略编辑器,并且认为应该可以访问,请确保你拥有管理员权限,并检查是否有任何系…...

将Spring boot 项目部署到tomcat服务艰难
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z X Y Z...
第十二章 ObjectScript - 命令
文章目录 第十二章 ObjectScript - 命令命令熟悉的命令用于多维数组的命令 第十二章 ObjectScript - 命令 命令 本节概述了在 ObjectScript 常用命令。其中包括与其他语言中的命令相似的命令,以及其他语言中没有等效项的其他命令。 命令名称不区分大小写…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...