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

相关推荐
王老师青少年编程1 小时前
2025年【江苏“信息与未来”编程思维】真题及题解(T2:坐标变换)
c++·题解·真题·坐标变换·编程思维·江苏·信息与未来
私人珍藏库1 小时前
[Android] PeakFinder AR v4.8.89 (山峰全景识别+增强现实山峰查看器)
android·人工智能·智能手机·ar·工具·软件
researcher-Jiang2 小时前
高性能计算之OpenMP——超算习堂学习1
android·java·学习
alexhilton3 小时前
Kotlin DSL深度解析:从Gradle脚本到构建你自己的DSL
android·kotlin·android jetpack
烽火聊员3 小时前
查看Android Studio错误日志
android·ide·android studio
2023自学中5 小时前
C++ 内存追踪器
linux·c++
星空语8 小时前
音频001_Android+Linux车载/手机音频全链路分层架构图
android·linux·音视频
CyL_Cly9 小时前
解决官网下载慢!Android Studio 最新版网盘下载
android·ide·android studio
智塑未来9 小时前
鸿蒙系统对比安卓、iOS,核心优势是什么?
android·ios·harmonyos
DogDaoDao9 小时前
【GitHub】 LLVM Project 深度解析:现代编译器基础设施的基石
java·c++·python·程序员·github·编译器·llvm