anroid平台NDK编译并调用.a静态库和.so动态库

开发环境:AS 3.1.4,Cmake编译,Ndk 17.1。

1. 编译静态库和动态库

1.新建一个“Include C++ support”的工程,确认local.properties和gradle.properties的配置:
anroid平台NDK编译并调用.a静态库和.so动态库
anroid平台NDK编译并调用.a静态库和.so动态库
2.在app的build.gradle中添加ndk支持:

  ndk{
            moduleName "libcam"
            stl "stlport_static"     //ndk中包含了stl对应的库
            ldLibs("log")
        }

3.在src->main下新建jni文件夹,将.c源码及文件夹放入该文件夹下,并在该文件夹下新建Android.mk文件和Application.mk文件。
anroid平台NDK编译并调用.a静态库和.so动态库
3.在Android.mk中写入abi信息即可:

APP_ABI := armeabi-v7a

4.在Application.mk中写入:动态库和静态库的区别只是最后一句:
anroid平台NDK编译并调用.a静态库和.so动态库
2.最后在DOS下进入jni目录下,执行ndk-build命令即可在\src\main\obj\local\armeabi-v7a下找到生成的静态/动态库。

2.使用静态库和动态库

静态(动态)库的使用方法和VS设置头文件、lib路径类似。在Android平台下,只需要在CMakeList.txt中进行设置,然后使用JNI调用对应的接口。项目结构如下:
anroid平台NDK编译并调用.a静态库和.so动态库
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下整个工程,调用成功。