anroid平台NDK编译并调用.a静态库和.so动态库
开发环境:AS 3.1.4,Cmake编译,Ndk 17.1。
1. 编译静态库和动态库
1.新建一个“Include C++ support”的工程,确认local.properties和gradle.properties的配置:
2.在app的build.gradle中添加ndk支持:
ndk{
moduleName "libcam"
stl "stlport_static" //ndk中包含了stl对应的库
ldLibs("log")
}
3.在src->main下新建jni文件夹,将.c源码及文件夹放入该文件夹下,并在该文件夹下新建Android.mk文件和Application.mk文件。
3.在Android.mk中写入abi信息即可:
APP_ABI := armeabi-v7a
4.在Application.mk中写入:动态库和静态库的区别只是最后一句:
2.最后在DOS下进入jni目录下,执行ndk-build命令即可在\src\main\obj\local\armeabi-v7a下找到生成的静态/动态库。
2.使用静态库和动态库
静态(动态)库的使用方法和VS设置头文件、lib路径类似。在Android平台下,只需要在CMakeList.txt中进行设置,然后使用JNI调用对应的接口。项目结构如下:
1.新建一个“Include C++ support”的工程,然后在app/libs下新建armabi-7a文件夹,将生成的静态库、动态库放入该文件夹下。
2.在app的build.gradle下添加如下配置:
1.工具链(可以不用设置)及C/C++支持设置:
externalNativeBuild { //defaultConfig中添加
cmake {
cppFlags "-frtti -fexceptions -fPIC"
arguments '-DANDROID_TOOLCHAIN=clang' //默认的工具链,clang支持gcc
// Sets optional flags for the C compiler.
// cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2"
}
}
ndk { //defaultConfig中添加
abiFilters 'armeabi-v7a'
}
2.静态/动态库路径:
sourceSets{ //defaultConfig外,android内添加
main{
jniLibs.srcDirs =['libs']
}
}
3.在CMakeList.txt中进行如下配置:注意如果在CPP中使用时用的C库,注意在引用接口处(/src/main/cpp/include下的头文件中)添加extern "C"告诉编译器以C的方式编译该接口。
# 1.添加并设置库头文件
set(CMAKE_VERBOSE_MAKEFILE on)
set(libs "${CMAKE_SOURCE_DIR}/libs")
# 解决shared library text segment is not shareable
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wall -v -Wl,--no-warn-shared-textrel")
# 2.添加并设置静态库路径
add_library( # Sets the name of the library.
sonix
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/sonix.cpp
src/main/cpp/sonix_jni.cpp ) #对应/src/main/cpp/下的CPP源码,此处采用JNI_OnLoad函数注册。
add_library(libopencv_java3
SHARED
IMPORTED ) #添加预编译动态库,只需要告诉CMAKE导入项目即可
set_target_properties( libopencv_java3
PROPERTIES IMPORTED_LOCATION
"${libs}/${ANDROID_ABI}/libopencv_java3.so")
add_library(libcam
STATIC
IMPORTED ) #添加预编译静态库,只需要告诉CMAKE导入项目即可
set_target_properties( libcam
PROPERTIES IMPORTED_LOCATION
"${libs}/${ANDROID_ABI}/libcam.a")
# 3.添加并设置静态库连接,预构建库与本地库相关联:
target_link_libraries( # Specifies the target library.
sonix
libcam
# Links the target library to the log library
# included in the NDK.
${log-lib} )
3.sync后Rebuild下整个工程,调用成功。