1. 程式人生 > >android-java與C++的相互呼叫-隨心

android-java與C++的相互呼叫-隨心

剛研究了java與C++的相互呼叫,趕緊記錄下來。。。
一、java呼叫C++

要想讓java呼叫C++,必須讓C++函式按著命名規則來。命名規則為
返回值 Java_包路徑_類名_函式名(JNIEnv* env,jobject obj);對應如下:
jint Java_com_ndk_testndk_TestHello_jnia(JNIEnv* env,jobject obj);
其中第二個引數為該類的物件,也就是TestHello的物件例子如下:
  1. //java程式碼
  2. publicclass TestHello {  
  3.     publicnative String jnia();  
  4.     static
     {  
  5.         // 載入libAppConfig.so庫檔案
  6.         // AppConfig是新增 Android Native Support時輸入的名稱
  7.         // 另外,通過修改Android.mk中的LOCAL_MODULE可以修改這個名稱
  8.         System.loadLibrary("TestNDK");  
  9.     }  
  10. }  
  11. //C++程式碼
  12. #include <string h="">  
  13. #include <jni h="">  
  14. #include <android log="" h="">  
  15. #include "TestNDK.h"
  16. #ifdef __cplusplus  //最好有這個,否則被編譯器改了函式名字找不到不要怪我
  17. extern "C" {  
  18. #endif  
  19. jint Java_com_ndk_testndk_TestHello_jnia(JNIEnv* env,jobject obj){  
  20.     return12;  
  21. }  
  22. #ifdef __cplusplus  
  23. }  
  24. #endif  
  25. </android></jni></string>  
二、C++呼叫java
C++呼叫java就會比較複雜了,先來了解一下基本的語法吧!
  1. JNIEnv* env;  
  2. jclass cls;//對用java的Class
  3. jobject obj;  
  4. jmethodID mid;//對映方法
  5. //構建一個Class
  6. cls = jniEnv->FindClass("com/ndk/testndk/TestHello");//寫上類的路徑
  7. //例項化物件
  8. //方法一
  9. obj = env->AllocObject(cls);  
  10. //方法二
  11. jmethodID obj_id = env->GetMethodID(cls,"<init>""()V");  
  12. TestProvider mTestProvider = env->NewObject(cls,obj_id);  
  13. //對映方法
  14. //其中"()Ljava/lang/String;",括號是引數,Ljava/lang/String;是返回值,如有引數string,即為"(Ljava/lang/String;)Ljava/lang/String;"
  15. //靜態
  16. mid = env->GetStaticMethodID(cls, "getStaticString","()Ljava/lang/String;");  
  17. //非靜態
  18. mid = env->GetMethodID(cls, "getString","()Ljava/lang/String;");  
  19. //呼叫方法
  20. //靜態:
  21. env->CallStaticObjectMethod(cls, mid);  
  22. //非靜態:
  23. env->CallVoidMethod(obj, mid,jstr);  
  24. </init>  
//-----------------開始寫程式碼-----------------------------------------------------------------------------
  1. //java部分
  2. publicclass TestHello2 {  
  3.     publicstatic String getStaticString(){  
  4.         return"Java靜態的返回值";  
  5.     }  
  6.     public String getString(String str){  
  7.         str += ",還有非靜態的。";  
  8.         Log.e("", str);  
  9.         return str;  
  10.     }  
  11. }  
  12. //C++部分
  13. jstring Java_com_ndk_testndk_TestHello_jnistr(JNIEnv* env,jobject obj){  
  14.     jclass cls = env->FindClass("com/ndk/testndk/TestHello2");  
  15.     jobject obj1 = env->AllocObject(cls);  
  16.     jmethodID mid1 = env->GetStaticMethodID(cls, "getStaticString","()Ljava/lang/String;");  
  17.     jmethodID mid2 = env->GetMethodID(cls, "getString","(Ljava/lang/String;)Ljava/lang/String;");  
  18.     //靜態:
  19.     jstring jstr = (jstring) env->CallStaticObjectMethod(cls, mid1);  
  20.     //非靜態:
  21.     jstring jstr2 = (jstring) env->CallObjectMethod(obj1, mid2,jstr);  
  22.     return jstr2;  
  23. }  

getStaticMethodInfo和getMethodInfo的最後一個引數如下圖


以下是一些易犯的錯誤整理:
1.在java函式若是String型的,在jni呼叫是傳參必須是env->NewStringUTF("這是字串")
Demo下載地址:http://download.csdn.net/detail/super_level/7041419