0、下載jdk並配置環境變量java
下載最新jdk,百度搜索「jdk」就有了。安裝完成後,配置環境變量(網上一搜,一堆,我這裏僅做簡要敘述)android
系統變量→新建 CLASSPATH 變量c++
變量值填寫 .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar(注意最前面有一點)eclipse
系統變量→尋找 Path 變量→編輯ide
在變量值最後輸入 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;函數
(注意原來Path的變量值末尾有沒有;號,若是沒有,先輸入;號再輸入上面的代碼)
系統變量配置完畢學習
一、官網下載最新的ADT。 解壓便可(eclipse最好自帶ndk插件)ui
二、官網下載最新的NDK。解壓便可(ndkr7以上有自帶cygwin)spa
三、eclipse沒有自帶插件,則下載插件。.net
插件網上有,我做爲本身學習,也在百度雲共享了一份,下載地址:http://pan.baidu.com/s/1i3xImQp
下載好插件放到eclipse下的plugins文件夾下。重啓eclipse。
四、重點開始
eclipse→window→preferences→Android→NDK
配置剛剛下載的ndk的路徑
五、新建android 項目
右擊→properties→C/C++ Build 。去掉默認的build command
設置成${NDKROOT}/ndk-build.cmd
再到build Variables 點擊add。配置如圖.name:NDKROOT value:你的ndk路徑。點擊肯定。
六、項目右鍵->Android Tools->Add Native Support...,輸入.so庫名字後點擊Finish
七、如今已經能夠Build咱們的Jni項目了,選擇項目,Project->Build Project,編譯咱們的c/c++代碼,此時項目結構以下,NDK plugin已經爲咱們添加好了include,已經爲咱們生成了相應的Android.mk以及 cpp文件。(注意:這裏插件爲咱們生成的是cpp文件,若你不喜歡能夠改回.c,並在mk文件中進行相應更改)
八、能夠運行咱們的Jni項目了。
遇到的問題
一、運行c++生成的.so庫,若報如下錯誤:(既找不到函數)
No implementation found for native Lcom/example/hellojni/MainActivity;.stringFromJNI ()Ljava/lang/String;
java.lang.UnsatisfiedLinkError: stringFromJNI
at com.example.hellojni.MainActivity.stringFromJNI(Native Method)
解決方法:
爲供Java調用的c++函數前加入extern "C" 修飾,如:(NDK example裏面的cpp文件也是這麼聲明的,參考hello-gl2)
緣由是:
被extern "C"修飾的變量和函數是按照C語言方式編譯和鏈接的。
首先看看C++中對相似C的函數是怎樣編譯的:做爲一種面向對象的語言,C++支持函數重載,而過程式語言C則不支持。函數被C++編譯後在符號庫中的名字與C語言的不一樣。例如,假設某個函數的原型爲:void foo( int x, int y );該函數被C編譯器編譯後在符號庫中的名字爲_foo,而C++編譯器則會產生像_foo_int_int之類的名字(不一樣的編譯器可能生成的名字不一樣,可是都採用了相同的機制,生成的新名字稱爲「mangled name」)。_foo_int_int這樣的名字包含了函數名、函數參數數量及類型信息,C++就是靠這種機制來實現函數重載的。例如,在C++中,函數voidfoo( int x, int y )與void foo( int x, float y )編譯生成的符號是不相同的,後者爲_foo_int_float。
一樣地,C++中的變量除支持局部變量外,還支持類成員變量和全局變量。用戶所編寫程序的類成員變量可能與全局變量同名,咱們以"."來區分。而本質上,編譯器在進行編譯時,與函數的處理類似,也爲類中的變量取了一個獨一無二的名字,這個名字與用戶程序中同名的全局變量名字不一樣。
所以,若咱們沒有使用extern "C"修飾函數,按照C語言方式編譯和鏈接,Jni調用將可能找不到該函數。