在Android Studio中使用预先构建的共享库

在Android Studio中使用预先构建的共享库,android,c++,c,cmake,android-ndk,Android,C++,C,Cmake,Android Ndk,我需要在我的android项目中使用一个定制的预构建共享库(作为libdynamic.so在独立ndk上构建)。我在src/main路径中创建了一个文件夹“jniLibs”,然后在其中创建了4个文件夹,即“armeabi”、“armeabi-v7a”、“x86”和“x86_64”。我已将预构建库放在所有这4个文件夹中 现在,我想从我的本地代码调用这个库的一个函数。以以下方式(包含在cmakelists.txt中的标题): 我发现以下错误: 错误:错误:找不到-ldynamic 错误:(19)未定

我需要在我的android项目中使用一个定制的预构建共享库(作为libdynamic.so在独立ndk上构建)。我在src/main路径中创建了一个文件夹“jniLibs”,然后在其中创建了4个文件夹,即“armeabi”、“armeabi-v7a”、“x86”和“x86_64”。我已将预构建库放在所有这4个文件夹中

现在,我想从我的本地代码调用这个库的一个函数。以以下方式(包含在cmakelists.txt中的标题):

我发现以下错误:

  • 错误:错误:找不到-ldynamic

  • 错误:(19)未定义对“rsqrt(float)”的引用

  • 错误:错误:链接器命令失败,退出代码为1(使用-v查看调用)

  • 似乎没有找到共享库。我在CMakeLists.txt中输入了以下值

    include_directories( src/main/cpp/include) #include header of libdynamic.so
    target_link_libraries(native-lib dynamic)  #dependency of native-lib on libdynamic.so
    
    我在gradle构建(应用程序)中添加了以下附加条目:


    我能够使用android push和android shell成功运行库。是使用Android Studio构建的apk造成了这个问题。我使用的是Android Studio 2.3.3版。非常感谢您的帮助

    为了在Android环境中加载带有CMake的库,您必须在native lib CMakeLists.txt中添加以下代码:

    设置libs路径
    set(LIBS\u DIR${CMAKE\u SOURCE\u DIR}/./jniLibs)

    添加要导入的库
    添加库(动态库共享导入)

    为每个ABI设置库位置
    设置目标属性(动态库属性)
    导入的位置${LIBS\u DIR}/${ANDROID\u ABI}/lidynamic.so)

    将导入的库链接到目标
    目标链接库(本机库动态库)


    在本机lib build.gradle中:

    defaultConfig{
        ...
        externalNativeBuild{
            // Specify the toolchain which was used to cross compile libdynamic.so because Android Studio assumes that you used clang
            arguments '-DANDROID_TOOLCHAIN=gcc'
        }
    }
    

    使用-L将sysroot lib dir添加到LDFLAGS,因为如果调用正确,libdynamic还依赖于libc、libdl,并且至少应该需要libm

    路径应为:


    $NDK/platforms/android-(platform version)/arch-(architecture)/usr/lib

    我能够使用android.mk而不是cmake使其工作。我正在发布Android.mk和gradlebuild的配置和内容,以防有人需要

    在“app”下创建一个文件夹“jni”。创建另一个自定义文件夹“yourlibs”,并将所有预构建的libs放入相应“TARGET_ARCH_ABI”文件夹中的“yourlibs”文件夹中。例如,在我的例子中:

    • jni/yourlibs/armeabi/libdynamic.so
    • jni/yourlibs/armeabi-v7a/libdynamic.so
    • jni/yourlibs/x86/libdynamic.so
    • jni/yourlibs/x86_64/libdynamic.so
    现在按照以下步骤操作:

  • 在“jni”文件夹中创建一个“C”文件,从中调用“libdynamic.so”中定义的函数。将必要的头文件添加到创建的“C”文件中。对我来说是“uselib.c”和“header.h”
  • 在“jni”文件夹中创建一个名为“Android.mk”的文件
  • 在Android.mk中添加以下内容

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_SRC_FILES := yourlibs/$(TARGET_ARCH_ABI)/libdynamic.so
    LOCAL_MODULE := add_prebuilt
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_SRC_FILES  := uselib.c
    LOCAL_MODULE     :=  use-lib
    LOCAL_SHARED_LIBRARIES := add_prebuilt
    include $(BUILD_SHARED_LIBRARY)
    
    更新gradle构建(应用程序)文件以使用“Android.mk”而不是cmake:

    在“android=>defaultConfig”中

    “安卓”内部

    这将创建一个名为“uselib”的库,该库使用“libdynamic.so”,并将这两个库打包到apk的lib文件夹中。您可以使用apk Analyzer(Android Studio=>Build=>analysis apk…)检查这一点。要使用“use lib”,请使用jni调用,如:

    static {
        System.loadLibrary("use-lib");
    }
    
    public native String stringFromJNI(); 
    

    注意:我从C代码中删除了extern“C”语句。

    嘿,泰坦,谢谢你的回答;但是使用您的配置,我收到以下错误:“错误:“../../../../../../../../JNILBS/x86/libdynamic.so”需要“../../../../../build/intermediates/cmake/debug/obj/x86/libnative lib.so”,缺少并且没有已知的规则来创建它“您有jni.srcDirs=['src/main/jNILBS/'”在native lib/build.gradle中?因为这就是告诉编译器共享lib的位置。答案如下:
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_SRC_FILES := yourlibs/$(TARGET_ARCH_ABI)/libdynamic.so
    LOCAL_MODULE := add_prebuilt
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_SRC_FILES  := uselib.c
    LOCAL_MODULE     :=  use-lib
    LOCAL_SHARED_LIBRARIES := add_prebuilt
    include $(BUILD_SHARED_LIBRARY)
    
     ndk{
            abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64'
        }
    
    externalNativeBuild {
        ndkBuild {
            path "jni/Android.mk"
        }
    }
    
    static {
        System.loadLibrary("use-lib");
    }
    
    public native String stringFromJNI();