交叉編譯
- 在一個平臺下,編譯出另一個平臺能夠執行的二進制的代碼
- 平臺:windows,mac os,linux
- 處理器:x86,arm,mips
交叉編譯的原理
- 源代碼->編譯->鏈接->可執行程序
- 模擬其他平臺的特性
交叉編譯的工具鏈
- 多個工具的集合,一個工具使用完后接著調用下一個工具
常見工具
- NDK:native developement kit:開發jni必備,就是模擬其他平臺特性來編譯代碼的工具
- CDT:C/C++ developement tools:高亮顯示c語言關鍵字
- cygwin:一個模擬器,可以再windows下運行linux指令
NDK目錄結構
- docs:幫助文檔
- build/tools:linux的批處理文件
- platforms:編譯c代碼需要使用的頭文件和類庫
- prebuilt:預編譯使用的二進制可執行文件
- sample:jni的使用例子
- source:ndk的源碼
- toolchains:工具鏈
- ndk-build.cmd:編譯打包c代碼的一個指令
使用jni
在項目根目錄下創建jni文件夾
在jni文件中創建一個c文件
-
在java代碼中,創建一個本地方法helloFromC
public native String helloFromC();
-
在jni中定義函數實現這個方法,函數名必須為
jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)
-
返回一個字符串,用c定義一個字符串
char* cstr = "hello from c";
-
把c的字符串轉換成java的字符串
jstring jstr = (*env)->NewStringUTF(env, cstr); return jstr;
在jni中創建Android.mk文件
在c文件中添加<jni.h>頭文件
在jni文件夾下執行ndk-build.cmd指令
java代碼中加載so類庫,調用本地方法
常見錯誤
-
findLibrary returned null
- CPU平臺不匹配
- 加載類庫時,寫錯類庫名字
-
本地方法找不到
- 忘記加載類庫
- c代碼中方法名寫錯了
javah
*1.7:在src目錄下執行javah 包名.類名
*1.6:在bin/classes目錄下執行
javap
- 在bin/class目錄下執行javap -s 包名.類名
- 打印方法簽名