带有静态库的 Android Studio 中的本机 C++ 代码

Posted

技术标签:

【中文标题】带有静态库的 Android Studio 中的本机 C++ 代码【英文标题】:Native C++ Code in Android Studio with a Static Library 【发布时间】:2020-02-14 07:01:07 【问题描述】:

我正在尝试在 android Studio 和 CMake 中制作原生 C++ 代码。我的 C++ 代码使用预编译的静态库(.a 文件)。 我在我的 C++ 代码中包含了它的头文件 .h。我还在我的 CMakeList.txt 中链接了 .h 和 .a 文件的位置,如下所示:

include_directories(".h file location")

然后:

add_library(lib_fastcv STATIC IMPORTED)

set_target_properties(lib_fastcv PROPERTIES IMPORTED_LOCATION
    ".a file location")

最后:

target_link_libraries (...lib_fastcv....)

但是,一旦我使用 .a 静态库中的任何函数,它就会抱怨它无法识别该函数,这意味着静态库未正确链接到我的 C++ 代码。

有人知道我还需要做什么吗? 我还应该编辑我的 build.gradle 以包含有关库文件的信息吗?

【问题讨论】:

您确定 .a 文件包含适合您正在编译的架构的代码吗?此外,CMake target_link_libraries 在参数之间不使用逗号。 我不确定。我有 .a 文件的 32 位和 64 位版本。我都尝试了,但没有奏效。我将尝试在 build.gradle 中指定一个特定的构建,看看它是否有效。对于 target_link_libraries ,你说得对,我只是在我的帖子中这样提到它并且已经编辑过它。 我将 build.gradle 配置为特定的 ABI,但仍然没有运气......我怀疑它可能与 CMake 版本与 .a 预构建文件不兼容有关。否则我不知道为什么它不能使用提供给它的 .a 文件! cmake版本与此无关。您正在编译什么架构,您的 .a 文件是什么架构,nm 是否证明缺少的符号在那里? 我搞定了。它与如何将 CMake 定向到现有代码 .a 文件以及如何告知 build.gradle 构建特定的 abi 格式有关。对我来说,它似乎仍然没有必要复杂!稍后我将发布与此问题相关的代码部分。感谢您的初步回复,它帮助我在正确的位置查找问题。 【参考方案1】:

这是我的解决方案: 所以,首先,CMake 一开始使用起来可能很奇怪。

1- native-lib1 是 CMake 的输出产品。以后java只会看到.so这个

add_library( # This is out .so product (libnative-lib1.so)
    native-lib1

    # Sets the library as a shared library.
    SHARED

    # These are the input .cpp source files
    native-lib.cpp
    SRC2.cpp
    Any other cpp/c source file you want to compile
    )

2- 您包含在 souse 文件中的任何库,其 .h 都需要在此处处理:

 target_include_directories(# This is out .so product (libnative-lib1.so)
    native-lib1 PRIVATE
    $CMAKE_SOURCE_DIR/include)

3- 您使用的任何实际库,其 atual .a 或 .cpp 都应以这种方式添加到 CMake:

target_link_libraries(
    # This is out .so product (libnative-lib1.so)
    native-lib1

    #These are any extra library files that I need for building my source .cpp files to final .so product
    $CMAKE_SOURCE_DIR/lib/libfastcv.a
    # Links the target library to the log library
    # included in the NDK.
    $log-lib)

然后 build.gradle 应该提到我们希望它制作什么 abi 格式以确保您预先构建的 .a 文件是兼容的。

flavorDimensions "version"
productFlavors 
    create("arm7") 
        ndk.abiFilters("armeabi-v7a")
    

最后,作为一个注释,下面的命令不能过滤 abis 和上面的命令工作,即使它们在逻辑和形式上对我来说看起来相似:

        cmake 
            cppFlags "-std=c++11"
            abiFilters 'armeabi-v7a'
        
    
    ndk 
        // Specifies the ABI configurations of your native
        // libraries Gradle should build and package with your APK.
        // This is not working to eliminate
        abiFilters 'armeabi-v7a'
    

【讨论】:

以上是关于带有静态库的 Android Studio 中的本机 C++ 代码的主要内容,如果未能解决你的问题,请参考以下文章

android studio 利用gradle和cmakelist生成c++静态库.a的方法总结

android studio开启虚拟机的时候显示 apk only support armeabi

Android Studio 3.0.1不会构建NDK静态库

Android Studio 中库的 NoClassDefFoundError [重复]

无法在 Android Studio 下创建 64 位库的 APK

并行构建 Visual Studio 解决方案会丢失一些静态库的 PDB