当前位置: 首页 > news >正文

Android ndk 编译opencv后部分接口std::__ndk1与项目std::__1不匹配

1、opencv-4.11预编译命令(在opencv4.5.0之后兼容免费features2d做特征匹配),NDK版本选用的android-ndk-r23c-linux.zip

cmake -G Ninja \
-DCMAKE_TOOLCHAIN_FILE=/home/who/Downloads/NDK/android-ndk-r23c/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=arm64-v8a \
-DANDROID_PLATFORM=android-31 \
-DANDROID_ARM_NEON=ON \
-DANDROID_STL=c++_shared \
-DCMAKE_CXX_FLAGS="-D_LIBCPP_ABI_NAMESPACE=__1 -D_LIBCPP_ABI_VERSION=1 -frtti -fexceptions -D__GXX_RTTI=1" \
-DENABLE_RTTI=ON \
-DENABLE_EXCEPTIONS=ON \
-DBUILD_SHARED_LIBS=ON\
-DOPENCV_EXTRA_MODULES_PATH=/home/who/Downloads/opencv-4.11/opencv_contrib/opencv_contrib-4.11.0/modules \
-DBUILD_LIST=features2d,core,imgproc,imgcodecs,videoio,highgui,calib3d,flann,stitching,photo \
-DBUILD_opencv_stitching=ON \
-DBUILD_opencv_features2d=ON \
-DBUILD_opencv_core=ON \
-DBUILD_opencv_imgproc=ON \
-DBUILD_opencv_imgcodecs=ON \
-DBUILD_opencv_videoio=ON \
-DBUILD_opencv_highgui=ON \
-DBUILD_opencv_calib3d=ON \
-DBUILD_opencv_flann=ON \
-DBUILD_opencv_photo=ON \
-DWITH_OPENCL=ON \
-DOPENCL_LIBRARY=/home/who/Downloads/opencv-4.11/vendor/lib64/libGLES_mali.so \
-DWITH_VULKAN=ON \
-DVULKAN_LIBRARY=/home/who/Downloads/opencv-4.11/system/lib64/libvulkan.so \
-DENABLE_NEON=ON \
-DBUILD_JPEG=ON \
-DBUILD_ANDROID_PROJECTS=OFF \
-DBUILD_JAVA=OFF \
-DBUILD_opencv_java=OFF \
-DBUILD_opencv_java_bindings_generator=OFF \
-DBUILD_ANDROID_EXAMPLES=OFF \
-DBUILD_TESTS=OFF \
-DWITH_TBB=ON \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-O3 -mcpu=cortex-a76 -mtune=cortex-a76 -funsafe-math-optimizations -g" \
..

其他配置包括:

     -DANDROID_ABI=arm64-v8a 设置64位库,如需要32位可以设置为armeabi-v7a;-DCMAKE_CXX_FLAGS 符号兼容;-DANDROID_STL=c++_shared  std命名空间依赖库,默认为c++_static.a-DOPENCV_EXTRA_MODULES_PATH 画面拼接需要的外部库;-DBUILD_SHARED_LIBS 开启动态库打包;-DWITH_OPENCL=ON \ -DOPENCL_LIBRARY \ -DWITH_VULKAN=ON \ -DVULKAN_LIBRARY 用于开启GPU处理配置;-DCMAKE_CXX_FLAGS 编译优化器;

采用ninja做并行编译,加速编译速度;
编译安装:ninja -j16 && ninja install

2、使用命令llvm-nm -gDC libopencv_features2d.so | grep “cv::DescriptorMatcher::knnMatch”

$ llvm-nm -gDC libopencv_features2d.so | grep "cv::DescriptorMatcher::knnMatch"
0005b5e4 T cv::DescriptorMatcher::knnMatch(cv::_InputArray const&, std::__ndk1::vector<std::__ndk1::vector<cv::DMatch, std::__ndk1::allocator<cv::DMatch> >, std::__ndk1::allocator<std::__ndk1::vector<cv::DMatch, std::__ndk1::allocator<cv::DMatch> > > >&, int, cv::_InputArray const&, bool)
0005b440 T cv::DescriptorMatcher::knnMatch(cv::_InputArray const&, cv::_InputArray const&, std::__ndk1::vector<std::__ndk1::vector<cv::DMatch, std::__ndk1::allocator<cv::DMatch> >, std::__ndk1::allocator<std::__ndk1::vector<cv::DMatch, std::__ndk1::allocator<cv::DMatch> > > >&, int, cv::_InputArray const&, bool) const
$ llvm-nm -gDC libopencv_imgcodecs.so | grep "cv::imwrite"
000da7b0 T cv::imwrite(std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, cv::_InputArray const&, std::__ndk1::vector<int, std::__ndk1::allocator<int> > const&)

可以看到接口符号是std::__ndk1,而当设备使用的std::__1符号编译。
这会导致这些接口应编译报错


ld.lld: error: undefined symbol: cv::DescriptorMatcher::knnMatch(cv::_InputArray const&, cv::_InputArray const&, std::__1::vector<std::__1::vector<cv::DMatch, std::__1::allocator<cv::DMatch> >, std::__1::allocator<std::__1::vector<cv::DMatch, std::__1::allocator<cv::DMatch> > > >&, int, cv::_InputArray const&, bool) const
>>> referenced by

3、修改NDK,重新编译opencv

<1> 修改NDK中的__config文件

who@who-virtual-machine:~/Downloads/NDK/android-ndk-r23c$ find -name __config
./toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/experimental/__config
./toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/__config
./sources/cxx-stl/llvm-libc++/include/experimental/__config
./sources/cxx-stl/llvm-libc++/include/__config

./toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/__config
./sources/cxx-stl/llvm-libc++/include/__config

这两个文件中ndk删去
在这里插入图片描述
<2>、替换NDK中libc++__shared.so
需要替换的路径

$ find -name libc++_shared.so
./toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/libc++_shared.so
./toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so
./toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so
./toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so
./sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so
./sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_shared.so
./sources/cxx-stl/llvm-libc++/libs/x86/libc++_shared.so

替换的库为需要合入的设备下libc++.so

 # find -name libc++.so
./system/apex/com.android.adbd/lib/libc++.so
./system/apex/com.android.adbd/lib64/libc++.so
./system/apex/com.android.art/lib/libc++.so
./system/apex/com.android.art/lib64/libc++.so
./system/apex/com.android.media/lib/libc++.so
./system/apex/com.android.media/lib64/libc++.so
./system/apex/com.android.runtime/lib/libc++.so
./system/apex/com.android.runtime/lib64/libc++.so
./system/apex/com.android.conscrypt/lib/libc++.so
./system/apex/com.android.conscrypt/lib64/libc++.so
./system/apex/com.android.media.swcodec/lib64/libc++.so
./system/apex/com.android.vndk.current/lib/libc++.so
./system/apex/com.android.vndk.current/lib64/libc++.so
./system/apex/com.android.i18n/lib/libc++.so
./system/apex/com.android.i18n/lib64/libc++.so
./system/apex/com.android.appsearch/lib64/libc++.so
./system/lib/libc++.so
./system/lib64/libc++.so

替换后同时重命名库为libc++_shared.so

下面是替换重新编译opencv:

$ llvm-nm -gDC libopencv_imgcodecs.so | grep "cv::imwrite"
000000000013d220 T cv::imwriteanimation(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::Animation const&, std::__1::vector<int, std::__1::allocator<int> > const&)
000000000013be50 T cv::imwrite(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::_InputArray const&, std::__1::vector<int, std::__1::allocator<int> > const&)
$ llvm-nm -gDC libopencv_features2d.so | grep "cv::DescriptorMatcher::knnMatch"
0000000000086570 T cv::DescriptorMatcher::knnMatch(cv::_InputArray const&, std::__1::vector<std::__1::vector<cv::DMatch, std::__1::allocator<cv::DMatch> >, std::__1::allocator<std::__1::vector<cv::DMatch, std::__1::allocator<cv::DMatch> > > >&, int, cv::_InputArray const&, bool)
0000000000086300 T cv::DescriptorMatcher::knnMatch(cv::_InputArray const&, cv::_InputArray const&, std::__1::vector<std::__1::vector<cv::DMatch, std::__1::allocator<cv::DMatch> >, std::__1::allocator<std::__1::vector<cv::DMatch, std::__1::allocator<cv::DMatch> > > >&, int, cv::_InputArray const&, bool) const

可以看到重新编译后opencv库已经可以兼容std::__1

参考链接
https://blog.csdn.net/weixin_41660527/article/details/135130517

http://www.xdnf.cn/news/204931.html

相关文章:

  • 【LeetCode 热题 100】矩阵置零 / 螺旋矩阵 / 旋转图像 / 搜索二维矩阵 II
  • 【Vagrant+VirtualBox创建自动化虚拟环境】Ansible测试Playbook
  • springboot 框架把 resources下的zip压缩包, springboot 项目启动后解压到项目根目录工具类
  • DeepSeek主动学习系统:低质量数据炼金术的工程化实践
  • runpod team 怎么设置自己的ssh key呢?
  • LLamaFactory如何在Windows系统下部署安装训练(保姆级教程)
  • 松下机器人快速入门指南(2025年更新版)
  • Kotlin-高阶函数,Lambda表达式,内联函数
  • IntelliJ IDEA 2024.3.1 for Mac 中文 Java开发工具
  • 狼人杀中的智能策略:解析AI如何理解复杂社交游戏
  • 语音合成之十韵律之美:TTS如何模拟语音的节奏和语调
  • 23种设计模式-行为型模式之中介者模式(Java版本)
  • 第10次:电商项目配置开发环境
  • 初探RAG
  • SQLyog中DELIMITER执行存储过程时出现的前置缩进问题
  • 在 Windows 的终端安装并使用 azd 命令
  • Windows权限与icacls命令详解
  • taro小程序如何实现大文件(视频、图片)后台下载功能?
  • 小结: 接口类型和路由优先级
  • 如何用python脚本把一个表格有4万多条数据分为两个文件表,每个2万条数据?
  • stm32wb55rg (4) 启用usart串口
  • PDM是什么?PDM有什么用?怎么选PDM?2025制造PDM/PLM系统盘点(4000字)
  • 针对信息过载问题的解决方案
  • 【Prometheus-MySQL Exporter安装配置指南,开机自启】
  • uni-app中使用RenderJs 使用原生js
  • 抱佛脚之学SSMSpringMVC数据绑定
  • 微服务学习笔记
  • 时序数据库 TDengine × Perspective:你需要的可视化“加速器”
  • OpenGL ES 3.0 第二章总结:你好,三角形(Hello Triangle)
  • AlDente Pro for Mac电脑 充电限制保护工具 安装教程【简单,轻松上手】