【问题标题】:How can I link a static library to a source used as an native library in NDK Android Build如何将静态库链接到在 NDK Android Build 中用作本机库的源
【发布时间】:2019-05-27 02:11:55
【问题描述】:

我想包含一个为提供的 C++ 代码构建的静态库,我尝试链接静态库,但构建无法链接该库。我收到以下错误:

对“Test_C_Interface”的未定义引用

我是 Java NDK/cmake 的新手。请帮我解决这个问题

这是使用的cpp代码(native-lib.cpp)

    extern int Test_C_Interface();

    extern "C" JNIEXPORT jstring JNICALL

    Java_com_example_tvgui_MainActivity_stringFromJNI(JNIEnv *env, jobject /* this */) {
        std::string hello = "From C++";

        int ret_val;

        ret_val = Test_C_Interface();

        if(ret_val == 100){
            hello = "From C";
        }
       return env->NewStringUTF(hello.c_str());
    }

这是用于制作静态库的c代码(sample.c/libsample.a)[使用NDK ARM-v7a ToolChain构建的库]

    #include<stdio.h>

    int Test_C_Interface(void)
    {
        printf("Inside C Library\n");

        return 100;
    }

这是cmake文件

    cmake_minimum_required(VERSION 3.4.1)

    add_library(
            native-lib
            SHARED
            native-lib.cpp)

    find_library( 
            log-lib
            log)

    target_link_libraries(
            native-lib
            ${log-lib}
            ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/libsample.a)

我需要像这样构建一个应用程序:

libsample.a
             \
              \
                ====libnative-lib.so + Java = .apk 
              /
             /
native-lib.cpp

更新 通过修改代码解决了这个问题:

extern "C"{ 
     int Test_C_Interface();
}

【问题讨论】:

    标签: java c++ cmake android-ndk


    【解决方案1】:

    您应该根据您的 ABI 将您的 libsample.a 放入以下结构的目录中,例如

    libs
    │   ├── x86/libsample.a
    │   ├── x86_64/libsample.a
    │   ├── arm64-v8a/libsample.a
    │   ├── armeabi-v7a/libsample.a
    
    

    然后更新你的 cmakefile 如下:

    target_link_libraries(
                native-lib
                ${log-lib}
                ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/<ANDROID_ABI>/libsample.a)
    

    请确保${CMAKE_CURRENT_SOURCE_DIR}/../../../libs 是正确的路径。

    对于 CMake 变量,例如ANDROID_ABI,可以参考Android NDK path variable in CMake build tool chain

    【讨论】:

    • 按照上面的修改,CMakeCache.txt 看起来像这样 ://Dependencies for the target native-lib_LIB_DEPENDS:STATIC=general;C:/Users/no101/AppData/Local/Android/Sdk/ndk -bundle/toolchains/llvm/prebuilt/windows-x86_64/sysroot/usr/lib/arm-linux-androideabi/16/liblog.so;general;C:/Users/no101/AndroidStudioProjects/TVGUI/app/src/main/ cpp/../../../libs/armeabi-v7a/libsample.a;----- 但得到同样的错误
    • 您首先需要确保两件事:1. 您的libsample.a 是使用Android NDK 构建的,如果您正确执行此操作,那么您应该有一个输出目录,如&lt;some-path&gt;/x86/libsample.a、@ 987654329@、&lt;some-path&gt;/arm64-v8a/libsample.a&lt;some-path&gt;/armeabi-v7a/libsample.a。 2、你应该确保${CMAKE_CURRENT_SOURCE_DIR}/../../../libs是一个真实存在的路径。
    • 在不同的机器上构建是可以的,但它应该(必须)使用 Android NDK 工具链构建。
    • 不客气!我回答堆栈溢出问题以赢得声誉,如果对您有帮助,请投票支持我的回答。谢谢!
    【解决方案2】:

    您可以使用 android-ndk 示例作为示例(示例如下)。这是link to android dev manuals - Native 库的解释。这是堆栈上的相同问题 - link

    在 ubuntu 上,静态/共享库的路径在这里(它是 android-ndk 示例):

    hello-jni/app/src/main/jniLibs/ [处理器] / [你的库]

    [Including a library, java file]

    static {
            System.loadLibrary("hello-jni");
    }
    

    [Cmake file]

    cmake_minimum_required(VERSION 3.4.1)
    
    add_library(hello-jni SHARED
                hello-jni.c)
    
    #Include libraries needed for hello-jni lib
    target_link_libraries(hello-jni
                          android
                          log)
    

    【讨论】:

    • 但是我需要链接一个已经建立在不同机器上的静态库
    • “根据您在评论中链接到的 JEP 178,您不必做任何不同的事情。System.loadLibrary 现在将同时加载动态和静态库”和“/app/src/ main/jniLibs/ [处理器] / [你的库]"
    • 我仍然有错误:错误:未定义对“Test_C_Interface()”clang++.exe 的引用:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)忍者:构建停止:子命令失败。即使库路径在 CMakeCache.txt 中更新
    • 你好,麦迪!您可能获得了这些 .a 静态二进制文件,而无需使用 Android NDK 工具链构建它们。甚至构建时的 Linux 静态文件也会生成 .a 文件。因此,您必须清楚您尝试链接的 .a 文件是使用 Android NDK 工具链生成的。
    猜你喜欢
    • 1970-01-01
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    相关资源
    最近更新 更多