【Android NDK 开发】NDK 交叉编译 ( Ubuntu 中交叉编译动态库 | Android Studio 中配置使用第三方动态库 )
文章目錄
- I . 動(dòng)態(tài)庫(kù) 與 靜態(tài)庫(kù)
- II . 編譯動(dòng)態(tài)庫(kù)
- III. Android Studio 使用第三方動(dòng)態(tài)庫(kù)
- IV . Android Studio 關(guān)鍵代碼
- V . 博客資源
I . 動(dòng)態(tài)庫(kù) 與 靜態(tài)庫(kù)
1 . 函數(shù)庫(kù)分類 : ① 動(dòng)態(tài)庫(kù) , ② 靜態(tài)庫(kù) ;
2 . 靜態(tài)庫(kù) :
編譯鏈接時(shí) , 將整個(gè)庫(kù)文件打包到可執(zhí)行文件中 , 造成可執(zhí)行文件較大 , 但運(yùn)行時(shí)不需要庫(kù)文件 ;
Android 與 Linux 靜態(tài)庫(kù) 后綴為 “.a” ;
3 . 動(dòng)態(tài)庫(kù) :
編譯鏈接時(shí) , 不將庫(kù)打包入可執(zhí)行文件中 , 在程序運(yùn)行時(shí)調(diào)用到該庫(kù)時(shí)才鏈接加載該動(dòng)態(tài)庫(kù) ;
Android 與 Linux 靜態(tài)庫(kù) 后綴為 “.so” ;
4 . 靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)對(duì)比 :
① 靜態(tài)庫(kù)時(shí)間效率高 : 執(zhí)行時(shí)沒有動(dòng)態(tài)鏈接的操作 , 所有的代碼都在可執(zhí)行文件內(nèi)部 , 時(shí)間消耗少 ;
② 動(dòng)態(tài)庫(kù)空間效率高 : 動(dòng)態(tài)庫(kù)如果被多個(gè)程序調(diào)用 , 只要有一個(gè)動(dòng)態(tài)庫(kù)在內(nèi)存中即可 ;
II . 編譯動(dòng)態(tài)庫(kù)
1 . 要編譯的源文件 : add.c 源文件 ;
#include <stdio.h>int add(int a, int b){return a + b; }2 . 共享動(dòng)態(tài)庫(kù)編譯參數(shù) : 編譯動(dòng)態(tài)庫(kù)需要添加 “-fPIC” 和 “-shared” 兩個(gè)參數(shù) ;
3 . 編譯命令 :
① 設(shè)置 編譯器 臨時(shí)環(huán)境變量 :
export CC=/home/book/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
② 設(shè)置指定 頭文件和函數(shù)庫(kù) 的臨時(shí)環(huán)境變量 :
export HEAD_LIB="--sysroot=/home/book/NDK/android-ndk-r17c/platforms/android-21/arch-arm -isystem /home/book/NDK/android-ndk-r17c/sysroot/usr/include -isystem /home/book/NDK/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi"
③ 最終命令 :
$CC $HEAD_LIB -fPIC -shared add.c -o libadd.so
4 . 編譯結(jié)果 : 在該目錄下生成了 libadd.so 動(dòng)態(tài)庫(kù) ;
book@book-virtual-machine:~/NDK$ export CC=/home/book/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc book@book-virtual-machine:~/NDK$ export HEAD_LIB="--sysroot=/home/book/NDK/android-ndk-r17c/platforms/android-21/arch-arm -isystem /home/book/NDK/android-ndk-r17c/sysroot/usr/include -isystem /home/book/NDK/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi" book@book-virtual-machine:~/NDK$ $CC $HEAD_LIB -fPIC -shared add.c -o libadd.so book@book-virtual-machine:~/NDK$ ls add.c android-ndk-r17c-linux-x86_64.zip libadd.so android-ndk-r17c a.out main.c book@book-virtual-machine:~/NDK$目錄中的 libadd.so 就是編譯完成的動(dòng)態(tài)庫(kù) , 該動(dòng)態(tài)庫(kù)可以放到 Android Studio 項(xiàng)目中使用 ;
III. Android Studio 使用第三方動(dòng)態(tài)庫(kù)
1 . 拷貝動(dòng)態(tài)庫(kù) :
在 AS 項(xiàng)目的 main 目錄下 , 創(chuàng)建 jniLibs/armeabi-v7a 目錄 , 將 libadd.so 拷貝到該目錄中 ;
2 . CMakeLists.txt 中配置動(dòng)態(tài)庫(kù) :
配置示例 :
# 設(shè)置變量 # CMAKE_CXX_FLAGS 表示會(huì)將 C++ 的參數(shù)傳給編譯器 # CMAKE_C_FLAGS 表示會(huì)將 C 參數(shù)傳給編譯器# 參數(shù)設(shè)置 : 傳遞 CMAKE_CXX_FLAGS C+= 參數(shù)給編譯器時(shí) , 在 該參數(shù)后面指定庫(kù)的路徑 # CMAKE_SOURCE_DIR 指的是當(dāng)前的文件地址 # -L 參數(shù)指定動(dòng)態(tài)庫(kù)的查找路徑 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a")3 . Module 級(jí)別的 build.gradle 中配置動(dòng)態(tài)庫(kù) :
在 android -> defaultConfig -> externalNativeBuild -> cmake 下添加 abiFilters "armeabi-v7a" 配置 ;
defaultConfig {...externalNativeBuild {cmake {cppFlags ""abiFilters "armeabi-v7a"}}}4 . 在 C++ 中調(diào)用該庫(kù) :
① 首先聲明該動(dòng)態(tài)庫(kù)中的方法 :
注意 : 這是在 C++ 語(yǔ)言中調(diào)用 C 語(yǔ)言方法 , 要使用 extern "C"{} 兼容 C 和 C++ 調(diào)用 ;
//調(diào)用 libadd.so 動(dòng)態(tài)庫(kù)中的方法 extern "C" { //注意在 C++ 中調(diào)用 C 語(yǔ)言方法 , 需要做兼容設(shè)置extern int add(int a, int b); }② 調(diào)用動(dòng)態(tài)庫(kù)中的函數(shù) : 之后就可以在該 C++ 文件中任意使用該方法了 ;
5 . 執(zhí)行結(jié)果 :
01-25 19:40:27.444 5929-5929/kim.hsl.makeflie I/JNI_TAG: libadd.so : sum = 3IV . Android Studio 關(guān)鍵代碼
1 . CMakeLists.txt 配置文件 :
2 . native-lib 本地 C++ 文件 :
3 . Module 級(jí)別的 build.gradle 配置文件 :
apply plugin: 'com.android.application'android {compileSdkVersion 29buildToolsVersion "29.0.0"defaultConfig {applicationId "kim.hsl.makeflie"minSdkVersion 15targetSdkVersion 29versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"externalNativeBuild {cmake {cppFlags ""abiFilters "armeabi-v7a"}}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}externalNativeBuild {cmake {path "src/main/cpp/CMakeLists.txt"version "3.10.2"}} }dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'androidx.appcompat:appcompat:1.1.0'implementation 'androidx.constraintlayout:constraintlayout:1.1.3'testImplementation 'junit:junit:4.12'androidTestImplementation 'androidx.test:runner:1.2.0'androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' }V . 博客資源
CSDN 博客地址 : 【Android NDK 開發(fā)】NDK 交叉編譯 ( Ubuntu 中交叉編譯動(dòng)態(tài)庫(kù) | Android Studio 中配置使用第三方動(dòng)態(tài)庫(kù) )
博客資源下載地址 : https://download.csdn.net/download/han1202012/12148685
示例代碼 GitHub 地址 : https://github.com/han1202012/004_NDK_Makeflie
總結(jié)
以上是生活随笔為你收集整理的【Android NDK 开发】NDK 交叉编译 ( Ubuntu 中交叉编译动态库 | Android Studio 中配置使用第三方动态库 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Android NDK 开发】NDK
- 下一篇: 【Android NDK 开发】Ubun