Cocos2d-x利用jni呼叫java層程式碼
jni的意思是java本地呼叫,通過jni可以實現java層程式碼和其他語言寫得程式碼進行互動。在Cocos2d-x中,如果想要在C++層呼叫java層的程式碼,就是通過jni技術。通過呼叫java層的程式碼,我們就可以在Android平臺下實現一些引擎沒有提供給我們的功能,或者做一些其他的功能。比如加個廣告,加個分享,呼叫Android原生的對話方塊等等吧。Cocos2d-x比較人性化的是為我們封裝了jni呼叫的一些介面,這個類就是JniHelper,我們只需要使用這個類提供給我們的介面就可以完成呼叫java層程式碼的功能。先說一下這個類的位置,因為自己在找的時候有點犯二,所以特意說明一下。在3.0和3.1以上的引擎版本中,這個類的位置分別如下。
3.1以後引擎把原來cocos目錄下的包含各個功能的資料夾都放到了cocos目錄下,我個人認為這樣的放法還是比較好的。就是引擎老改目錄,希望以後不要放來放去了。最主要的當然是看看怎麼使用JniHelper這個類了。
首先使用之前要包含標頭檔案,寫法如下,記住要加上條件編譯,這個東西是Android平臺下才用到。
1 2 3 4 5 6 |
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/jni/JniHelper.h" #include <jni.h>
#endif
|
接著通過一小段程式碼來說明一下這個類的用法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
// typedef struct JniMethodInfo_
// {
// JNIEnv * env; // jclass classID;
// jmethodID methodID;
// } JniMethodInfo;
JniMethodInfo info;
//getStaticMethodInfo判斷java定義的靜態函式是否存在,返回bool
bool ret = JniHelper::getStaticMethodInfo(info, "org/cocos2dx/cpp/TestJni" , "func1" , "()V" );
if (ret)
{
log ( "call void func1() succeed" );
//傳入類ID和方法ID,小心方法名寫錯,第一個字母是大寫
info.env->CallStaticVoidMethod(info.classID,info.methodID);
}
#endif
|
大家書寫程式碼的時候同樣需要將程式碼使用條件編譯寫到裡面,JniMethodInfo是一個結構體,這個結構體的定義就是程式碼中註釋掉的地方,然後使用JniHelper呼叫了靜態函式getStaticMethodInfo,從它的名字就知道這個函式的作用了,就是獲得java層中靜態函式的資訊,這個資訊儲存在什麼地方呢,當然是JniMethodInfo中了,我們要獲取哪個類的哪個函式呢,第二個引數和第三個引數就是告訴JniHelper我們要獲取的是哪個函式的資訊了,第二個引數是類檔案的包名路徑,我在org/cocos2dx/cpp這個路徑下新建了一個類,叫做TestJni。其實前面的路徑就是一個包名,這裡使用的時候用/代替.。org的路徑當然就是我新建的這個工程的Android平臺目錄了。一會我要將這個專案打包然後測試一下,在eclipse下看看輸出。第三個引數當然就是方法名字了,第四個引數是需要注意的一個,有人把它叫做簽名,其實就是你要呼叫的java層函式的返回值和引數的型別說明。它把呼叫函式的引數寫到前面的括號中,返回值跟在括號的後邊,和我們平時書寫函式的時候正好相反了。那那個V是什麼東西呢,這個大寫字母就是對應的一個型別,如果是void型別,那麼就用一個V來代替,如果是一個int型別,那麼就用一個I代替,是不是很簡單,那其他的型別呢,如圖所示。
放了兩張表,用得時候查就好了,關於這個引數其他的細節問題待會討論。整個函式的返回值是一個bool型別,什麼意思不用說了吧。當這個函式的資訊存在的時候我們就進入到了if中了,然後我使用了info結構體的第一個變數來呼叫了函式CallStaticVoidMethod,這個函式可真是需要說一說。
首先它的呼叫者就是儲存函式資訊的結構體JniMethodInfo的第一個成員變數env,這貨是什麼東西不用管,用就好了。
然後這個函式的第一個字母是大寫,這一點要小心,Call後邊如果跟Static代表的就是我要呼叫的是一個靜態的函式,如果沒有那就不是靜態的,不是靜態的函式,我們使用JniHelper獲取資訊的時候用得就是getMethodInfo這個函式。然後Void代表的是函式的返回值,來看我們的例子,我呼叫的函式func1是一個無參無返回值的函式,這個看什麼地方,當然java程式碼我接著會向你展示,但是你可以直接看getStaticMethodInfo這個函式的第四個引數啊。這裡的這個void代表的是函式的返回值型別,所以如果呼叫的是返回值為int的java函式,那就是CallStaticIntMethod了。裡邊的引數就是結構體info的第二個和第三個成員變量了,代表的是類ID和函式ID。這樣的話基本的用法就說清楚了,接著就是TestJni中得程式碼了,我把要呼叫到得函式都寫了出來。