各位大佬
正在开发一个安卓 app,用到 jni,在 c++ 里调用 opencv 。但是 opencv 始终不能连接成功,链接时错误日志(截几行)如下:
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/release/obj/local/arm64-v8a/objs/native-lib/native_jni.o: In function `String':
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/jni/include/opencv2/core/cvstd.hpp:602: undefined reference to `cv::String::allocate(unsigned long)'
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/release/obj/local/arm64-v8a/objs/native-lib/native_jni.o: In function `Java_com_turingvideo_robot_jni_NativeHelper_drawText':
/Users/rqs/proj/android_robot/src/main/jni/native_jni.cpp:150: undefined reference to `cv::putText(cv::_InputOutputArray const&, cv::String const&, cv::Point_<int>, int, double, cv::Scalar_<double>, int, int, bool)'
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/release/obj/local/arm64-v8a/objs/native-lib/native_jni.o: In function `~String':
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/jni/include/opencv2/core/cvstd.hpp:648: undefined reference to `cv::String::deallocate()'
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/release/obj/local/arm64-v8a/objs/native-lib/native_jni.o: In function `String':
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/jni/include/opencv2/core/cvstd.hpp:602: undefined reference to `cv::String::allocate(unsigned long)'
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/release/obj/local/arm64-v8a/objs/native-lib/native_jni.o: In function `Java_com_turingvideo_robot_jni_NativeHelper_drawText':
/Users/rqs/proj/android_robot/src/main/jni/native_jni.cpp:151: undefined reference to `cv::putText(cv::_InputOutputArray const&, cv::String const&, cv::Point_<int>, int, double, cv::Scalar_<double>, int, int, bool)'
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/release/obj/local/arm64-v8a/objs/native-lib/native_jni.o: In function `~String':
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/jni/include/opencv2/core/cvstd.hpp:648: undefined reference to `cv::String::deallocate()'
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/release/obj/local/arm64-v8a/objs/native-lib/native_jni.o: In function `String':
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/jni/include/opencv2/core/cvstd.hpp:602: undefined reference to `cv::String::allocate(unsigned long)'
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/release/obj/local/arm64-v8a/objs/native-lib/native_jni.o: In function `Java_com_turingvideo_robot_jni_NativeHelper_drawText':
/Users/rqs/proj/android_robot/src/main/jni/native_jni.cpp:153: undefined reference to `cv::putText(cv::_InputOutputArray const&, cv::String const&, cv::Point_<int>, int, double, cv::Scalar_<double>, int, int, bool)'
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/release/obj/local/arm64-v8a/objs/native-lib/native_jni.o: In function `~String':
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/jni/include/opencv2/core/cvstd.hpp:648: undefined reference to `cv::String::deallocate()'
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/release/obj/local/arm64-v8a/objs/native-lib/native_jni.o: In function `String':
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/jni/include/opencv2/core/cvstd.hpp:602: undefined reference to `cv::String::allocate(unsigned long)'
我理解 undefined reference 就是链接时找不到某个符号的实现,一般是因为某个库的缺失、某个库的版本不对,类型不匹配。
我找到了构建工具执行的链接语句,也比较长:
/Users/rqs/Library/Android/sdk/ndk/21.3.6528147/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++\
-Wl,-soname,libnative-lib.so\
-shared\
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/native-lib/native_jni.o\
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/native-lib/src/arucotag.o\
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/native-lib/src/utils.o\
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/native-lib/src/occupancy_grid.o\
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/native-lib/src/occupancy_grid_jni.o\
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/native-lib/src/virtual_wall_grid_jni.o\
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/native-lib/src/virtual_wall_grid.o\
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/staticlibs/arm64-v8a/libopencv_aruco.a\
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/staticlibs/arm64-v8a/libopencv_highgui.a\
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/staticlibs/arm64-v8a/libopencv_calib3d.a\
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/staticlibs/arm64-v8a/libopencv_imgproc.a\
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/3rdparty/libs/arm64-v8a/libcpufeatures.a\
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/3rdparty/libs/arm64-v8a/libtegra_hal.a\
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/staticlibs/arm64-v8a/libopencv_core.a\
-lgcc\
-Wl,--exclude-libs,libgcc.a\
-Wl,--exclude-libs,libgcc_real.a\
-latomic\
-Wl,--exclude-libs,libatomic.a\
/Users/rqs/proj/android_robot/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/libc++_shared.so\
-target\
aarch64-none-linux-android21\
-no-canonical-prefixes\
-Wl,--build-id\
-ljnigraphics\
-nostdlib++\
-Wl,--no-undefined\
-Wl,--fatal-warnings\
-llog -ldl -lz -lm -lc -lm\
-o /Users/rqs/proj/android_robot/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/libnative-lib.so
拿错误里提到的cv::String::deallocate()
来说,我在我指定的 libopencv_core 这个静态库中能够找到这个实现,nm 显示如下:
[19:44:57] rqs:opencv_prebuilt git:(1e0923e*) $ nm -CA /Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/staticlibs/arm64-v8a/libopencv_core.a | grep deallocate | grep ' T '
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/staticlibs/arm64-v8a/libopencv_core.a:matrix.cpp.o: 0000000000000000 T cv::Mat::deallocate()
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/staticlibs/arm64-v8a/libopencv_core.a:stl.cpp.o: 0000000000000000 T cv::String::deallocate()
/Users/rqs/proj/android_robot/opencv_prebuilt/sdk/native/staticlibs/arm64-v8a/libopencv_core.a:umatrix.cpp.o: 0000000000000000 T cv::UMat::deallocate()
可见里面有代码段的全局的 cv::String::deallocate
,它是一个不接受参数的函数,所以不会因为参数类型不匹配导致整体不匹配。
既然提供了这个静态链接库,库里面也有它的实现,为什么还是会有链接错误呢?请指教,谢谢!
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.