給Android增加分享庫.so文件

http://www.linuxidc.com/Linux/2010-08/28191.htm

Android工程文件夾中,我們可以通過jni機制來調用c/c++編寫的本地共享庫,例如libtest.so

在java文件中聲明一個靜態的調用,和共享庫中要調用的函數

test.java中

static{

system.loadlibrary("test");

}

static native int test(int i);

相應在相關的c/c++ 文件中按照jni的編寫規則編寫即可,Android自己增加了一個當loadlibrary時會調用jni_onload , jni_unload函數,這個不是重點。

我要提供的是so文件交叉編譯的方法。

Android提供了ndk及相關mk文件的寫法用來給編程人員編寫c/c++本地文件,但我看了一下並不習慣這種編譯方式,懶得去弄明白。所以決定還是按照原來的交叉編譯方式進行

1.首先在源碼中尋找/prebuild/linux-x86/tooltrain/arm-eabi-4.x.1/bin/這個目錄下的編譯文件,在~/.bashrc中將編譯使用的gcc, g++, ar等定義相應變數cc,cpp,ar為arm編譯器,並在make file中使用相應變數來編譯

2.在編譯so時要加上 -nostdlib 參數,不然系統會去鏈接標準庫發生ld的錯誤

例如: $CPP -shared -nostdlib -fpic -o libtest.so -c test.o (test.c 生產test.o文件時需要-I 源碼中的dalvik/libnativehelper/include/nativehelper文件夾,不然會因缺少頭文件導致編譯失敗)

3.將生產的so文件拷貝到工程 /libs/armeabi/ 下,調用即可

解釋幾個基本概念:

1. 在linux中用ar -cvr -o libabcd.a ab.o cd.o 編譯會生成.a文件,這個稱為靜態庫或歸檔庫,可以在編譯的時候加入.a一起編譯,(gcc -o main main.o -L. -labcd)運行時程序會copy靜態庫中的代碼段。-L後面跟靜態庫所屬目錄,-l後為靜態庫名稱,系統會自動過濾掉lib 和.a

2. .so文件生成 gcc -shared -fpic -o libabcd.so libabcd.a

so文件為共享庫,相當於dll,在運行時要調用時才去載入共享庫中代碼 可執行文件編譯方式與.a類似。

3.為什麼要加入nostdlib,因為Android沒有用linux的libc庫,而是使用自己的c函數庫


推薦閱讀:

【分享筆記】謝晶老師 夜話港樂
房子是長期居住的,裝修千萬別馬虎大意!分享我裝修的實用經驗
分享幾道牛肉湯麵的做法
一份圓環陽性場的檢測數據分享:保育呼吸道,母豬流產...

TAG:Android | 分享 | 文件 | 加分 |