当前位置: 首页 > 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

相关文章:

  • 4.27搭建用户界面
  • 前端vue2修改echarts字体为思源黑体-避免侵权-可以更换为任意字体统一管理
  • 天能资管(SkyAi):全球布局,领航资管新纪元
  • 线程数据同步的三种方式
  • Ansible 守护 Windows 安全(Ansible Safeguards Windows Security)
  • 大数据测试集群环境部署
  • Java实现使用EasyExcel按模板导出文件
  • 论文笔记-多智能体任务分配:动态智能空间中的拍卖与抢占机制
  • MySQL事务(transaction)(笔记)
  • redis 有序集合zrange和zrangebyscore的区别
  • 基础排序方法
  • 学习记录:DAY20
  • 【每日八股】复习 MySQL Day3:锁
  • Android Studio for Platform(ASFP)真机调试
  • Allegro23.1新功能之如何显示中文界面操作指导
  • LangChain入门(四) 部署应用程序
  • unity Orbbec Femto Bolt接入unity流程记录 AzureKinectExamples 插件 使用记录
  • TA学习之路——2.4 图形传统光照模型详解
  • Python 使用一等函数实现设计模式(案例分析:重构“策略”模式)
  • JAVA设计模式——(九)工厂模式
  • 外交部亚洲司司长刘劲松向菲方严肃交涉
  • 观察|英国航母再次部署印太,“高桅行动”也是“高危行动”
  • 第1现场|无军用物资!伊朗港口爆炸已遇难40人伤1200人
  • 伊朗港口爆炸最新情况:14死700多伤,大火延烧,调查困难
  • 新希望去年归母净利润4.74亿同比增逾九成,营收降27%
  • 国铁集团:一季度全国海铁运输商品车同比增长33.62%