踩坑JNI

作者: Zz鱼丸 | 来源:发表于2019-06-25 11:29 被阅读0次

使用Android studio3.4.1,即最新版时。使用cmake调用opencv3.2的jni库,出现

[1/8] Building CXX object src/main/cpp/2_10_recognitionHQB/CMakeFiles/recognitionHQB.dir/__/inc/NL_Face_Recognition/NL_FaceRecognition.cpp.o
[2/8] Building CXX object src/main/cpp/2_10_recognitionHQB/CMakeFiles/recognitionHQB.dir/__/inc/NL_Face_aligner/aligner.cpp.o
[3/8] Building CXX object src/main/cpp/2_10_recognitionHQB/CMakeFiles/recognitionHQB.dir/__/inc/NL_Face_MultiAttr/NL_MultiAttrPrediction.cpp.o
[4/8] Building CXX object src/main/cpp/2_10_recognitionHQB/CMakeFiles/recognitionHQB.dir/faceRecognitionHQBAPI.cpp.o
[5/8] Building CXX object src/main/cpp/2_10_recognitionHQB/CMakeFiles/recognitionHQB.dir/recognitionHQB.cpp.o
[6/8] Building CXX object src/main/cpp/2_10_recognitionHQB/CMakeFiles/recognitionHQB.dir/__/inc/NL_Face_Detection/NL_FaceDetection.cpp.o
[7/8] Building CXX object src/main/cpp/2_10_recognitionHQB/CMakeFiles/recognitionHQB.dir/__/inc/NL_Face_MultiAttr/NL_MultiAttrPredictionUtil.cpp.o
[8/8] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\armeabi-v7a\librecognitionHQB.so
FAILED: cmd.exe /C "cd . && D:\AndroidSDK\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe  --target=armv7-none-linux-androideabi24 --gcc-toolchain=D:/AndroidSDK/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=D:/AndroidSDK/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -march=armv7-a -mthumb -mfpu=neon -Wa,--noexecstack -Wformat -Werror=format-security  -std=c++11 -fopenmp -O0  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--exclude-libs,libunwind.a -Wl,--no-undefined -Qunused-arguments -Wl,-z,noexecstack -shared -Wl,-soname,librecognitionHQB.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\armeabi-v7a\librecognitionHQB.so @CMakeFiles/recognitionHQB.rsp  && cd ."
E:\Document\My\EmbedAI\AndroidSDK\NL_IDC_SDK\Project\NLFaceBaab\app\src\main\cpp\2_10_recognitionHQB/recognitionHQB.cpp:583: error: undefined reference to 'cv::imwrite(cv::String const&, cv::_InputArray const&, std::__ndk1::vector<int, std::__ndk1::allocator<int> > const&)'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(matrix.cpp.o):matrix.cpp:function std::vector<unsigned char, std::allocator<unsigned char> >::resize(unsigned int, unsigned char): error: undefined reference to 'std::__throw_length_error(char const*)'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(matrix.cpp.o):matrix.cpp:function std::vector<int, std::allocator<int> >::resize(unsigned int, int): error: undefined reference to 'std::__throw_length_error(char const*)'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(matrix.cpp.o):matrix.cpp:function std::vector<unsigned char, std::allocator<unsigned char> >::_M_fill_insert(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char, std::allocator<unsigned char> > >, unsigned int, unsigned char const&): error: undefined reference to 'std::__throw_length_error(char const*)'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(matrix.cpp.o):matrix.cpp:function std::vector<cv::Vec<unsigned char, 2>, std::allocator<cv::Vec<unsigned char, 2> > >::_M_fill_insert(__gnu_cxx::__normal_iterator<cv::Vec<unsigned char, 2>*, std::vector<cv::Vec<unsigned char, 2>, std::allocator<cv::Vec<unsigned char, 2> > > >, unsigned int, cv::Vec<unsigned char, 2> const&): error: undefined reference to 'std::__throw_length_error(char const*)'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(system.cpp.o):system.cpp:function _GLOBAL__sub_I_system.cpp: error: undefined reference to 'std::ios_base::Init::Init()'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(system.cpp.o):system.cpp:function _GLOBAL__sub_I_system.cpp: error: undefined reference to 'std::ios_base::Init::~Init()'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(ocl.cpp.o):ocl.cpp:function std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) [clone .part.43]: error: undefined reference to 'std::basic_ios<char, std::char_traits<char> >::clear(std::_Ios_Iostate)'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(ocl.cpp.o):ocl.cpp:function std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::~basic_stringbuf(): error: undefined reference to 'std::locale::~locale()'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(ocl.cpp.o):ocl.cpp:function std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::~basic_stringbuf(): error: undefined reference to 'std::string::_Rep::_M_destroy(std::allocator<char> const&)'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(ocl.cpp.o):ocl.cpp:function std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::~basic_stringbuf(): error: undefined reference to 'std::string::_Rep::_S_empty_rep_storage'

D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_core.a(ocl.cpp.o):ocl.cpp:function std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::~basic_stringbuf(): error: undefined reference to 'vtable for std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >'

google得知是因为编译这些静态库时所用的编译器、标准库等跟NDK当前的版本不同。网上的建议都是stl改为gnustl_static或gnustl_shared之类。但是尝试之后均失败,经分析都是未定义的引用时是否抛出错误,因此更改build.gradle

添加-DANDROID_ALLOW_UNDEFINED_SYMBOLS=TRUE
cmake {
                arguments "-DANDROID_ARM_NEON=TRUE" ,
                        "-DANDROID_TOOLCHAIN=clang++",
                        "-DANDROID_STL=c++_static",
                        "-DANDROID_PLATFORM=android-24",
                        "-DANDROID_ALLOW_UNDEFINED_SYMBOLS=TRUE"
                cppFlags "-std=c++11 -fopenmp"
                abiFilters "armeabi-v7a"
            }
···
编译通过

如何在 gradle 中使用 cmake 的变量

android {
  ...
  defaultConfig {
    ...
    externalNativeBuild {
      cmake {
        cppFlags "-frtti -fexceptions" // 通常不在这里配置 cppFlags 了
        ...
        // 使用下面这种语法向变量传递参数:
        // arguments "-D变量名=参数".
        arguments "-DANDROID_ARM_NEON=TRUE",
        // 使用下面这种语法向变量传递多个参数(参数之间使用空格隔开):
        // arguments "-D变量名=参数1 参数2"
                  "-DANDROID_CPP_FEATURES=rtti exceptions"
      }
    }
  }
  buildTypes {...}
  
  externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
  }
}

CMake 编译 NDK 所支持的变量配置


图片.png

附表(C++ 库支持)

图片.png
参考:https://developer.android.com/ndk/guides/cpp-support#system

相关文章

  • 踩坑JNI

    使用Android studio3.4.1,即最新版时。使用cmake调用opencv3.2的jni库,出现 go...

  • JNI入门踩坑

    要用Java 8 。10把javah这个工具给移除了

  • [Android ]JNI 入门踩坑

    大家好,我系苍王。 以下是我这个系列的相关文章,有兴趣可以参考一下,可以给个喜欢或者关注我的文章。 [Androi...

  • 安卓开发通过JNI调用本地方法

    今天开发中第一次接触到对jni方法的调用,特此记录在开发踩过的坑。 java通过JNI调用c/c++编写的本地方法...

  • visual studio编写jni踩坑

    这个东西说简单也简单,但是一不小心就如坑,以至于导致我多次踩坑都没成功,今天总算成功了!1、新建项目要使用空项目,...

  • JNI的GC locker坑[转载]

    江南白衣--JNI的gc坑

  • JNI容易踩坑的细节记录

    一、关于sig签名 这个方法传了2个参数,第一个是String:Ljava/lang/String;,第二个是in...

  • Android Studio3.0 NDK配置与开发

    前言 最近在学习JNI开发, 查阅 和网上很多文章, 发现很多知识都已经过时了, 经过一天的踩坑, 最终还是在官方...

  • JNI静态注册和动态注册

    JNI开发看似简单,但是初学者,通过搜索引擎东拼西凑的资料来写代码,几乎一定会踩坑,比方内存泄露,引用泄漏以及各种...

  • 【Android】AS添加JNI支持

    JNI入坑 索引: 旧 NDK 使用姿势(AS 2.2 以下 参考链接:Create hello-JNI wi...

网友评论

      本文标题:踩坑JNI

      本文链接:https://www.haomeiwen.com/subject/dmxtcctx.html