windows下android NDK 環境配置

0、下載jdk並配置環境變量java

下載最新jdk,百度搜索「jdk」就有了。安裝完成後,配置環境變量(網上一搜,一堆,我這裏僅做簡要敘述)android

  1.     計算機→屬性→高級系統設置→高級→環境變量。
  2. 系統變量→新建 JAVA_HOME 變量 。變量值填寫jdk的安裝目錄(本人是 D:\Program Files\Java\jdk1.7.0_45)
  3. 系統變量→新建 CLASSPATH 變量c++

    變量值填寫   .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar(注意最前面有一點)eclipse

  4. 系統變量→尋找 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)

 

[java]  view plain copy
 
 
  1. extern "C" {  
  2.     JNIEXPORT jstring JNICALL Java_com_dgut_android_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz );  
  3. }  
  4.   
  5. JNIEXPORT jstring JNICALL Java_com_dgut_android_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz )  
  6. {  
  7.     return env->NewStringUTF("Hello from JNI bear c++");  
  8. }  

緣由是:

 

        被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調用將可能找不到該函數。

相關文章
相關標籤/搜索