三、Android版本:
1歌逢、ndk開發(fā)必要的基礎(chǔ)知識(shí):
原本想配套寫一下ndk開發(fā)方面的基礎(chǔ)和步驟签杈,但老實(shí)說,這也并非三言兩語就能描述清楚的沽一,好在簡(jiǎn)書上已經(jīng)有現(xiàn)存的文章了未辆,經(jīng)過該作者同意,本人就引用一下:@zzyyppqq,thanks
關(guān)于開發(fā)工具的選擇
2014年的時(shí)候锯玛,基本都是使用eclipse來開發(fā)咐柜,使用android mk來編譯ndk程序。但是目前都是使用AndroidStudio做為開發(fā)和編譯ndk的工具攘残,因此我們關(guān)注AndroidStudio上的實(shí)現(xiàn)和編譯拙友。
.mk構(gòu)建系統(tǒng)demo
zzyyppqq-超級(jí)簡(jiǎn)單的Android Studio jni 實(shí)現(xiàn)(無需命令行)
通過使用ndk提供的工具來編譯ndk程序。
根據(jù)上述文檔歼郭,總結(jié)一下開發(fā)ndk的流程以及編譯過程:
1) public native String getString();在類中用native關(guān)鍵字聲明一個(gè)成員方法
2) 調(diào)用javah程序遗契,自動(dòng)生成navtie方法對(duì)應(yīng)的.h文件,得到可怕的c/c++函數(shù)原型:
JNIEXPORT jstring JNICALL Java_com_zhangyp_higo_myndk_MyNdk_getString (JNIEnv *, jobject);
3) 在.c或.cpp文件中實(shí)現(xiàn)上面javah自動(dòng)生成的函數(shù)
4) 編寫mk文件病曾,用于編譯生成.so(類linux系統(tǒng)的動(dòng)態(tài)鏈接庫)文件
包括Application.mk和android.mk這兩個(gè)mk文件
5) 你可以先調(diào)用一下ndk-build clear命令清理一下工程緩存之類的(有時(shí)不清理會(huì)出現(xiàn)一些問題),然后再調(diào)用ndk-build命令用于生成.so文件
6) 在android 類中使用static { System.loadLibrary("MyLibrary"); }方式牍蜂,將剛才生成的.so加載進(jìn)來漾根,然后就按照正常的android開發(fā)流程進(jìn)行native函數(shù)調(diào)用了。
由此可見鲫竞,Ndk的開發(fā)也不是很難辐怕,只要記住上面幾個(gè)步驟,就可以進(jìn)行簡(jiǎn)單的ndk開發(fā)从绘。
要點(diǎn):能夠被java調(diào)用的c/c++庫必須是以.so動(dòng)態(tài)鏈接庫方式鏈接進(jìn)來的寄疏,但是在ios開發(fā)中,必須要使用.lib靜態(tài)鏈接庫方式鏈入僵井,這是兩者很大的區(qū)別陕截。
技術(shù)在發(fā)展,時(shí)代在進(jìn)步批什。隨著AndroidStudio的普及农曲,引入了新的構(gòu)建系統(tǒng):gradle系統(tǒng)后,我們可以不用寫.mk文件了
要知道驻债,一個(gè)稍微復(fù)雜一點(diǎn)的ndk項(xiàng)目乳规,要在.mk中撰寫很多命令,單單.mk命令參考就有n多頁却汉,太可怕了Q蓖!
gradle構(gòu)建系統(tǒng)Demo
zzyyppqq-Android Studio使用gradle-experimental構(gòu)建NDK工程(無需Android.mk合砂、Application.mk文件)
gradle構(gòu)建注意點(diǎn):
1) gradle使用ndk編譯青扔,必須要使用:gradle-experimental 插件,這個(gè)需要到android相關(guān)網(wǎng)站去下載的
2) 一定要注意gradle-experimental的版本號(hào)與gradle的對(duì)應(yīng)關(guān)系翩伪,不能搞混了微猖。曾經(jīng)我因?yàn)闆]注意這一點(diǎn),導(dǎo)致掉在坑里兩天沒出來缘屹。太痛苦了(見下圖說明)凛剥。
3) 一定要按照上文提到的步驟曾我,一步步設(shè)置客们,zzyyppqq的gradle設(shè)置流程很清楚,就當(dāng)武功口訣來使用丝蹭,否則掉在坑里你也不知道怎么回事互亮。
4) 代碼的開發(fā)流程和.mk demo差不多犁享,只是不需要編寫.mk文件以及調(diào)用ndk-build命令了,這是使用gradle-experimental獲得的最大好處豹休。
再次強(qiáng)調(diào)一下:
gradle-experimental插件與gradle的版本號(hào)對(duì)應(yīng)關(guān)系圖:
gradle構(gòu)建文檔參考炊昆,請(qǐng)戳這里
使用gradle構(gòu)建系統(tǒng)后,雖然省掉了.mk文件的撰寫,但是很麻煩:
1)需要在java類中用native聲明方法
2)需要用Javah生成.h頭文件
3)需要在實(shí)現(xiàn).h中的函數(shù)時(shí)候凤巨,很熟悉java中的數(shù)據(jù)類型和c/c++中的數(shù)據(jù)類型之間的對(duì)應(yīng)關(guān)系
例如JNIEnv视乐,jobject,jstring等敢茁,還有其他很多數(shù)據(jù)類型佑淀,可以自己參看ndk開發(fā)文檔。
4)需要有時(shí)調(diào)用如此長(zhǎng)名字的函數(shù):Java_com_zhangyp_higo_myndk_MyNdk_getString
有沒有辦法解決上面提到的那些問題呢?
.........我們的豬腳.......SWIG庫......出場(chǎng)了......
有了SWIG后卷要,我們就可以正常方式編寫C/C++代碼渣聚,然后自動(dòng)包裝成ndk jni調(diào)用独榴,不需要了解android ndk數(shù)據(jù)類型僧叉,不需要javah調(diào)用,也不需要native聲明棺榔,Let's go! go! go! go!
2瓶堕、SWIG篇章:
SWIG簡(jiǎn)介:
SWIG全稱是Simplified Wrapper and Interface Generator,官方網(wǎng)站是http://www.swig.org/症歇。SWIG是一個(gè)開發(fā)工具郎笆,能夠?qū)⑹褂肅或者C++編寫的軟件與其他各種高級(jí)編程語言進(jìn)行嵌入聯(lián)接。
SWIG目前支持輸出的語言列表:
SWIG的安裝:
1)很簡(jiǎn)單忘晤,官網(wǎng)下載宛蚓,解壓到**最好沒有中文字符的**文件夾下
2)由于要使用swig.exe命令行程序,最好設(shè)置一下環(huán)境變量
3) 在命令行中輸入swig -help设塔,出現(xiàn)各種命令參數(shù)凄吏,說明環(huán)境變量設(shè)置成功。
AndroidStudio與SWIG配合流程:
1) 嚴(yán)格按照zzyyppqq的文檔配置好gradle以及gradle-experimental的參數(shù)
2) 在AndroidStudio中按zzyyppqq文檔創(chuàng)建jni文件夾
3) 將用c/c++混合編程方式為ios/android實(shí)現(xiàn)一個(gè)自繪日期選擇控件(一)中的
calendarCore.h和calendarCore.cpp文件復(fù)制到j(luò)ni文件夾下面,如下圖:
4) 編寫swig.i文件(接口文件)闰蛔,用于描述如何輸出.h文件為java接口痕钢,.i表示interface
5) 編寫generate.bat文件用于調(diào)用swig.exe自動(dòng)生成接口文件(很多個(gè),具體我們圖示)
雙擊運(yùn)行bat前后效果如下:
6) swig轉(zhuǎn)換的流程分析:
7) c/c++中的struct和class會(huì)自動(dòng)生成java對(duì)應(yīng)的類序六,并自動(dòng)添加(如果需要的話)get/set函數(shù):請(qǐng)查看CGPoint.java SCalendar.java等源碼
8) c/c++中的輸出參數(shù)任连,例如void calendar_get_year_month(SCalendar* calendar,int* year,int* month);
int* year 和 int* month是傳地址方式,將結(jié)果傳出來例诀,對(duì)于java來說随抠,必須要裝箱(boxing)以及拆箱(unboxing)
將int傳值方式變?yōu)閭饕梅绞剑虼俗詣?dòng)生成了SWIG_TYPE_p_int.java類繁涂,用于將值類型變?yōu)橐妙愋?
到此為止拱她,SWIG的使命已經(jīng)完成了,接下來純粹屬于Android java的控件開發(fā)爆土,其中會(huì)經(jīng)常調(diào)用上面分析過的由SWIG自動(dòng)生成的Java類椭懊。
3、 Android版Calendar的源碼:
源碼不再分析,實(shí)現(xiàn)細(xì)節(jié)可以參考
用c/c++混合編程方式為ios/android實(shí)現(xiàn)一個(gè)自繪日期選擇控件-IOS實(shí)現(xiàn)
Android版所有的源碼請(qǐng)狠狠地戳這里
https://github.com/jackyblf/
4氧猬、 到此背犯,c/c++結(jié)合ios/android原生開發(fā)的文章結(jié)束了,花了兩個(gè)禮拜盅抚,將近13000字漠魏。也算是嘔心瀝血吧。 如果覺得有用妄均,請(qǐng)關(guān)注我一下柱锹,謝謝
說明:
關(guān)于一些原創(chuàng)的文章,除非是一些第三方經(jīng)典源碼分析丰包,否則我一定會(huì)提供相應(yīng)的demo禁熏。