在Android Studio中使用预建的共享库 [英] Using Pre-built Shared Library in Android Studio
问题描述
我需要在我的android项目中使用自定义的预构建共享库(基于独立ndk构建为libdynamic.so).我在路径src/main中创建了一个文件夹"jniLibs",然后在其中创建了4个文件夹,即"armeabi","armeabi-v7a","x86","x86_64".我已经将预构建的库放在所有这4个文件夹中.
I need to use a custom prebuilt shared library (built on standalone ndk as libdynamic.so) in my android project. I created a folder "jniLibs" in path src/main and then 4 folders inside that namely "armeabi" "armeabi-v7a" "x86" "x86_64". I have put the prebuilt library inside all these 4 folders.
现在从我的本机代码中,我想调用该库的函数.通过以下方式(包含在cmakelists.txt中的标头):
Now from my native code I want to call a function of this library. In the following way (included header in cmakelists.txt):
extern "C"
JNIEXPORT jstring JNICALL
Java_demo_co_ru_jnilibtest_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
float inv = rsqrt(3); //FUNCTION FROM LIBRARY (libdynamic.so)
std::string hello = "Hello ";
return env->NewStringUTF(hello.c_str());
}
我收到以下错误:
-
Error:error: cannot find -ldynamic
Error:(19) undefined reference to 'rsqrt(float)'
Error:error: linker command failed with exit code 1 (use -v to see invocation)
似乎没有找到共享库.我在CMakeLists.txt中输入了以下值
It seems that shared library is not getting located. I entered following values in 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构建(应用程序)中添加了以下其他条目:
I added following additional entries inside my gradle build (app):
defaultConfig {
ndk{
abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64'
}
}
sourceSets {
main {
jni.srcDirs = ['src/main/jni', 'src/main/jniLibs/']
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
我能够使用android push和android shell成功运行该库.这是使用Android Studio的apk构建引起的.我正在使用Android Studio版本2.3.3.任何帮助都将受到高度赞赏.
I am able to successfully run the library using android push and android shell. It is the apk build using Android Studio that is causing problem. I am using Android Studio version 2.3.3. Any help is highly appreciated.
推荐答案
我能够使用Android.mk(而不是cmake)使其工作.我发布Android.mk的配置和内容,并构建gradle,以防万一有人需要它.
I was able to make it work using Android.mk instead of cmake. I am posting configurations and contents of Android.mk and gradle build just in case any one needs it.
在应用"下创建一个文件夹"jni".创建另一个自定义文件夹"yourlibs",并将所有预先构建的库放在相应的"TARGET_ARCH_ABI"文件夹中的"yourlibs"文件夹中.例如,就我而言:
Create a folder "jni" under "app". Create another custom folder "yourlibs" and put all your pre-built libs inside this "yourlibs" folder in respective "TARGET_ARCH_ABI" folder. For Example, in my case:
- jni/yourlibs/armeabi/libdynamic.so
- jni/yourlibs/armeabi-v7a/libdynamic.so
- jni/yourlibs/x86/libdynamic.so
- jni/yourlibs/x86_64/libdynamic.so
现在请按照以下步骤操作:
Now follow these steps:
- 在"jni"文件夹中创建一个"C"文件,您将在其中调用"libdynamic.so"中定义的函数.将必要的头文件添加到您创建的"C"文件中.对我来说是"uselib.c"和"header.h"
- 在"jni"文件夹中创建一个名为"Android.mk"的文件
在Android.mk中添加以下内容
Add following contents in 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 build(应用)文件更新为使用"Android.mk"而不是cmake:
Update gradle build (app) file to use "Android.mk" instead of cmake:
在"android => defaultConfig"内部
Inside "android => defaultConfig"
ndk{
abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64'
}
在"android"内部
Inside "android"
externalNativeBuild {
ndkBuild {
path "jni/Android.mk"
}
}
这将创建一个名为"use-lib"的库,该库使用"libdynamic.so",并将这两个库都打包在apk的lib文件夹中.您可以使用apk分析器(Android Studio => Build => Analyze Apk ...)进行检查.要使用"use-lib",请使用jni调用,例如:
This will make a library called "use-lib" that uses "libdynamic.so" and it will pack both the libraries inside the lib folder of apk. You can check this using apk analyser (Android Studio => Build => Analyse Apk ...). To use "use-lib" use jni call, like:
static {
System.loadLibrary("use-lib");
}
public native String stringFromJNI();
注意:我从C代码中删除了extern"C"语句.
Note: I removed extern "C" statement from the C code.
这篇关于在Android Studio中使用预建的共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!