在Android Studio中使用预先构建的共享库
我需要在我的android项目中使用一个定制的预构建共享库(作为libdynamic.so在独立ndk上构建)。我在src/main路径中创建了一个文件夹“jniLibs”,然后在其中创建了4个文件夹,即“armeabi”、“armeabi-v7a”、“x86”和“x86_64”。我已将预构建库放在所有这4个文件夹中 现在,我想从我的本地代码调用这个库的一个函数。以以下方式(包含在cmakelists.txt中的标题): 我发现以下错误:在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)未定
错误:错误:找不到-ldynamic
错误:(19)未定义对“rsqrt(float)”的引用
错误:错误:链接器命令失败,退出代码为1(使用-v查看调用)
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
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();