Ndk jni 调用opencv踩过的坑

一、NDK编译版本的问题

当你使用的是Android studio默认的版本,或者ndk16及以上版本进行ndk-build编译,可能会出现以下错误:
/build/core/add-application.mk:178: *** Android NDK: APP_STL gnustl_shared is no longer supported. Please switch to either c++_static or c++_shared. See https://developer.android.com/ndk/guides/cpp-support.html for more information. . Stop.
这是因为你使用的android studio3中的NDK版本太高了,NDK16之后就不支持gnustl_shared的编译了,此时你应该换成c++_static 或者 c++_shared编译。

二、关于链接库的问题

当你使用ndk进行编译时,一定会要配置一下build.grable,截图如下。
Alt text

如果你要这么配置的话,在jni文件夹下进行ndk-build编译时完全没有问题的,但是当你点击运行的时候,可能会出现如下错误:

More than one file was found with OS independent path ‘lib/arm64-v8a/libOpenCV.so’
Alt text

这是因为在新版的Gradle实现了自动打包编译so文件的功能,并且为so文件指定了默认的目录app/src/main/jniLibs,理论上默认的是没有这个文件夹的,我们只需要新建一个jniLibs文件夹并将so文件复制到该文件夹下,编译运行即可。
但是需要补充的是,在andriod studio中,在工程选项中,选择Android,如下图
在这里插入图片描述

当你进行ndk-build之后,这个菜单栏中是默认生成JniLibs文件夹的,如下图:
Alt text

但是在Project选项菜单中还是显示的是libs文件夹,如图
Alt text

此时你不必就这一个问题,你就认为android studio中默认生成了jniLibs文件夹,所以此时你就要修改下build.grable,屏蔽掉指定生成库文件目录代码,编译后运行就好了,代码如下:

sourceSets {
    main() {
        //jniLibs.srcDirs = ['/work/h_course/android/NdklinkOPecv1/app/src/main/libs'] //指定生成库文件目录   把这一句代码屏蔽掉
        jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
    }
}

三、建立关联

你的ndk-build可以编译通过,mk配置也没问题,运行的时候出现以下错误。

Build command failed.
Error while executing process /home/book/Android/Sdk/ndk-bundle/ndk-build with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/work/h_course/android/NdkDemoTest5/app/src/main/jni/Android.mk NDK_APPLICATION_MK=/work/h_course/android/NdkDemoTest5/app/src/main/jni/Application.mk APP_ABI=arm64-v8a NDK_ALL_ABIS=arm64-v8a NDK_DEBUG=1 APP_PLATFORM=android-21 NDK_OUT=/work/h_course/android/NdkDemoTest5/app/build/intermediates/ndkBuild/debug/obj NDK_LIBS_OUT=/work/h_course/android/NdkDemoTest5/app/build/intermediates/ndkBuild/debug/lib APP_CFLAGS+=-D_EXAMPLE_C_FLAG1 APP_CFLAGS+=-D_EXAMPLE_C_FLAG2 APP_CPPFLAGS+=-D__STDC_FORMAT_MACROS /work/h_course/android/NdkDemoTest5/app/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/libOpenCV.so}
[arm64-v8a] Compile++ : OpenCV <= com_example_book_ndkdemotest5_NDKUtils.cpp
In file included from /work/h_course/android/NdkDemoTest5/app/src/main/jni/com_example_book_ndkdemotest5_NDKUtils.cpp:7:
In file included from /work/h_course/android/NdkDemoTest5/app/src/main/jni/native/jni/include/opencv2/opencv.hpp:65:
In file included from /work/h_course/android/NdkDemoTest5/app/src/main/jni/native/jni/include/opencv2/flann.hpp:48:
In file included from /work/h_course/android/NdkDemoTest5/app/src/main/jni/native/jni/include/opencv2/flann/flann_base.hpp:40:
In file included from /work/h_course/android/NdkDemoTest5/app/src/main/jni/native/jni/include/opencv2/flann/params.h:33:
/work/h_course/android/NdkDemoTest5/app/src/main/jni/native/jni/include/opencv2/flann/any.h:58:51: error: cannot use typeid with -fno-rtti
virtual const std::type_info& type() { return typeid(T); }
^
/work/h_course/android/NdkDemoTest5/app/src/main/jni/native/jni/include/opencv2/flann/any.h:274:31: error: cannot use typeid with -fno-rtti
if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
^
/work/h_course/android/NdkDemoTest5/app/src/main/jni/native/jni/include/opencv2/flann/any.h:283:31: error: cannot use typeid with -fno-rtti
if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast();
^
/work/h_course/android/NdkDemoTest5/app/src/main/jni/native/jni/include/opencv2/flann/any.h:291:34: error: cannot use typeid with -fno-rtti
return policy->type() == typeid(anyimpl::empty_any);
^
/work/h_course/android/NdkDemoTest5/app/src/main/jni/native/jni/include/opencv2/flann/any.h:311:34: error: cannot use typeid with -fno-rtti
return policy->type() == typeid(T);
^
5 errors generated.
make: *** [/work/h_course/android/NdkDemoTest5/app/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/OpenCV/com_example_book_ndkdemotest5_NDKUtils.o] Error 1

这时候你是相当崩溃的,但是不要急,我给你分析原因。
原因就是你做了多余的一步骤.
当你在build.gradle中配置好了链接库,然后又从菜单中选择 Link C++ Project with Gradle
Alt text
Alt text

此时运行就会出现错误,解决放法就是把手动配置的删掉就可以了。

下面我给大家演示一下两种配置方式。

1、手动配置

目录仅供参考

 externalNativeBuild {
        ndkBuild {
            path file('/work/h_course/android/NdkDemoTest5/app/src/main/jni/Android.mk')
        }
    }
2、菜单配置

1、从 IDE 左侧打开 Project 窗格并选择 Android 视图。
2、右键点击您想要关联到原生库的模块(例如 app 模块),并从菜单中选择 Link C++ Project with Gradle。从下拉菜单中,选择ndk-build。使用 Project Path 旁的字段指定Android.mk文件路径。
Alt text
借鉴博主;
https://www.jianshu.com/p/92fdedddd177

四、ndk版本和opencv产生冲突解决方式

前文已经说过,opencv3及以下的版本仅仅支持gnustl_shared编译,但是NDK16之后就不支持gnustl_shared的编译了,所以这就到了一个十字路口。要你就使用低于16版本的ndk,要么就是用opencv4。如果你的ndk版本升级了,可能也会产生如下错误,提示找不到库。

/build/core/add-application.mk:178: *** Android NDK: APP_STL gnustl_shared is no longer supported. Please switch to either c++_static or c++_shared. See https://developer.android.com/ndk/guides/cpp-support.html for more information. . Stop.

下面我给你们分别介绍这两种解决方法:

1、使用ndk15

载掉as默认的最新版本,操作如下
Alt text
Alt text

然后去掉Android NDK前面的勾,点击ok就会完成卸载。

Alt text

接下来需要下载一个ndk15版本,给你们提供一个链接,里面有各个版本。

https://blog.csdn.net/shuzfan/article/details/52690554
下载完毕后需要解压文件,将解压路径设置为:Android Studio的SDK目录里,并命名为ndk-bundle。

2、使用opencv4

借鉴下面的帖子。
https://blog.csdn.net/firing00/article/details/87537635

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值