1. 程式人生 > >anroid平臺NDK編譯並呼叫.a靜態庫和.so動態庫

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下整個工程,呼叫成功。