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

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

powershell 复制代码
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" \
..

其他配置包括:

powershell 复制代码
     -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"

powershell 复制代码
$ 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
powershell 复制代码
$ 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符号编译。

这会导致这些接口应编译报错

powershell 复制代码
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文件

powershell 复制代码
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

powershell 复制代码
./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

需要替换的路径

powershell 复制代码
$ 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

powershell 复制代码
 # 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:

powershell 复制代码
$ 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&)
powershell 复制代码
$ 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

相关推荐
2501_915909066 分钟前
深度解析 iOS 内存占用,构建多工具协同的内存诊断、监控与优化体系
android·ios·小程序·https·uni-app·iphone·webview
sang_xb16 分钟前
深入解析 HashMap:从存储架构到性能优化
android·java·性能优化·架构
xlq2232225 分钟前
23.二叉树搜索树(下)
数据结构·c++·算法
Source.Liu28 分钟前
【学写LibreCAD】Rust Vector2D 实现与 C++ RS_Vector 的对应关系及优势分析
c++·rust·cad
蚂蚁取经34 分钟前
Qt C++ 小部件 QCustomPlot 的使用
c++·qt·信息可视化
爱装代码的小瓶子35 分钟前
【c++知识铺子】最后一块拼图-多态
java·开发语言·c++
啃火龙果的兔子1 小时前
android studio运行下载gradle特别慢怎么处理
android·ide·android studio
qq_296544651 小时前
安卓手机投屏电脑端教程,手机投屏教程,可以手机和电脑互传文件。电脑管理手机文件和APP等操作
android·智能手机·电脑
无限进步_1 小时前
C语言文件操作函数解析
c语言·开发语言·数据库·c++·后端·visual studio
我的offer在哪里1 小时前
MySQL 高频细节问题(覆盖性能、存储、运维、故障排查,补充前文未深入的核心细节)
android·运维·mysql