1. 新增 C++ 檔案
2. 查看 Java Method Signature
3. Java 呼叫 C++ 函數
4. C++ 呼叫 Java 函數
5. Java 呼叫 C++ 時傳遞數字變數
6. C++ 呼叫 Java 時傳遞數字變數
7. Java 呼叫 C++ 時傳遞字串
8. C++ 呼叫 Java 時傳遞字串
9. Java 呼叫 C++ 時傳遞矩陣
10. C++ 呼叫 Java 時傳遞矩陣
11. Java 呼叫 C++ 時傳遞回呼函數
12. C++ 呼叫 Java 時傳遞回呼函數
1. C++ 新增 .h/.cpp 檔案 :
i. 在 Classes 資料夾內新增 .h/.cpp 檔案
ii. 編輯 proj.android/jni/Android.mk :
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := cocos2dcpp_shared LOCAL_MODULE_FILENAME := libcocos2dcpp #新增的檔案加在 LOCAL_SRC_FILES LOCAL_SRC_FILES := hellocpp/main.cpp \ ../../Classes/AppDelegate.cpp \ ../../Classes/HelloWorldScene.cpp \ ../../Classes/AMGamebarUtil.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes LOCAL_WHOLE_STATIC_LIBRARIES += cocos2dx_static LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static LOCAL_WHOLE_STATIC_LIBRARIES += chipmunk_static LOCAL_WHOLE_STATIC_LIBRARIES += cocos_extension_static include $(BUILD_SHARED_LIBRARY) $(call import-module,cocos2dx) $(call import-module,cocos2dx/platform/third_party/android/prebuilt/libcurl) $(call import-module,CocosDenshion/android) $(call import-module,extensions) $(call import-module,external/Box2D) $(call import-module,external/chipmunk)2. 查看 Java Method Signature :
javap -s -classpath <path to jar file> <package name>.<class name> javap -s -classpath ./AMGameBar.jar com.appmaster.AMCocos2dxInterface javap -s com.appmaster.AMCocos2dxInterface (尚未壓縮成jar, 相對路徑 com/appmaster/AMCocos2dxInterface.class)3. Java 呼叫 C++ 函數 :
i. JAVA 檔案如下 :
package com.appmaster; import org.cocos2dx.lib.Cocos2dxActivity; import android.app.Activity; public class AMCocos2dxInterface { //1.定義 private static native void nativeLoginHandler(); ... static public void callNative(){ //2. 呼叫 c method nativeLoginHandler(); } }ii. C++ 檔案如下 :
#include "cocos2d.h" #include <jni/JniHelper.h> #include <jni.h> ... extern "C" { //c method 定義 : //Java_<package name (replace point with under line)>_<class>_<method> void Java_com_appmaster_AMCocos2dxInterface_nativeLoginHandler(JNIEnv* env, jobject thiz) { CCLOG("I HAVE BEEN TRIGGERED BY JAVA !"); } ... }4. C++ 呼叫 Java 函數 :
i. C++ 檔案如下 :
#include "cocos2d.h" #include <jni/JniHelper.h> #include <jni.h> ... JNIEnv *env =NULL; jclass classid; jmethodID methodid; JavaVM* jvm = cocos2d::JniHelper::getJavaVM(); if (NULL == jvm) { return; } //setup env jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4); if (ret !=JNI_OK) { env =NULL; return; } classid =env->FindClass("com/appmaster/AMCocos2dxInterface"); if (!classid){ return; } methodid =env->GetStaticMethodID(classid, "initGameBarLib", "()V"); if (!methodid){ return; } env->CallStaticObjectMethod(classid, methodid);ii. JAVA 檔案如下 :
package com.appmaster; import org.cocos2dx.lib.Cocos2dxActivity; import android.app.Activity; public class AMCocos2dxInterface { static public void initGameBarLib(){ ... } }
5. Java 呼叫 C++ 時傳遞數字變數 :
i. JAVA 檔案如下 :
package com.appmaster; import org.cocos2dx.lib.Cocos2dxActivity; import android.app.Activity; public class AMCocos2dxInterface { private static native void nativeMethod(int val); ... static public void run(){ nativeMethod(9527); } }ii. C++ 檔案如下 :
#include "cocos2d.h" #include <jni/JniHelper.h> #include <jni.h> ... extern "C" { void Java_com_appmaster_AMCocos2dxInterface_ nativeMethod(JNIEnv* env, jobject thiz, jint val) { int nval =(int)val; CCLOG("val=%d", nval); ... } ... }6. C++ 呼叫 Java 時傳遞數字變數 :
i. C++ 檔案如下 :
#include "cocos2d.h" #include <jni/JniHelper.h> #include <jni.h> ... JNIEnv *env =NULL; jclass classid; jmethodID methodid; JavaVM* jvm = cocos2d::JniHelper::getJavaVM(); if (NULL == jvm) { return; } //setup env jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4); if (ret !=JNI_OK) { env =NULL; return; } classid =env->FindClass("com/appmaster/AMCocos2dxInterface"); if (!classid){ return; } methodid =env->GetStaticMethodID(classid, "magicNumber", "(I)V"); if (!methodid){ return; } env->CallStaticObjectMethod(classid, methodid, (jint)9527);ii. JAVA 檔案如下 :
package com.appmaster; import org.cocos2dx.lib.Cocos2dxActivity; import android.app.Activity; public class AMCocos2dxInterface { static public void magicNumber(int val){ ... } }7. Java 呼叫 C++ 時傳遞字串 :
i. JAVA 檔案如下 :
package com.appmaster; import org.cocos2dx.lib.Cocos2dxActivity; import android.app.Activity; public class AMCocos2dxInterface { private static native void nativeMethod(final string data); ... static public void run(){ nativeMethod("hello C++"); } }ii. C++ 檔案如下 :
#include "cocos2d.h" #include <jni/JniHelper.h> #include <jni.h> ... extern "C" { void Java_com_appmaster_AMCocos2dxInterface_ nativeMethod(JNIEnv* env, jobject thiz, jstring data) { const char* pData =env->GetStringUTFChars(data, 0); CCLOG("data=%s", pData); ... env->ReleaseStringUTFChars(data, pData); } ... }8. C++ 呼叫 Java 時傳遞字串 :
i. C++ 檔案如下 :
#include <jni/JniHelper.h> #include <jni.h> ... JNIEnv *env =NULL; jclass classid; jmethodID methodid; JavaVM* jvm = cocos2d::JniHelper::getJavaVM(); if (NULL == jvm) { return; } //setup env jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4); if (ret !=JNI_OK) { env =NULL; return; } classid =env->FindClass("com/appmaster/AMCocos2dxInterface"); if (!classid){ return; } methodid =env->GetStaticMethodID(classid, "initGameBarLib", "(Ljava/lang/String;Ljava/lang/String;)V"); if (!methodid){ return; } jstring arg0 =env->NewStringUTF(pArg0); //char* pArg0 jstring arg1 =env->NewStringUTF(pArg1); //char* pArg1 env->CallStaticObjectMethod(classid, methodid, arg0, arg1); env->DeleteLocalRef(arg0); env->DeleteLocalRef(arg1);ii. JAVA 檔案如下 :
package com.appmaster; import org.cocos2dx.lib.Cocos2dxActivity; import android.app.Activity; public class AMCocos2dxInterface { static public void initGameBarLib(String arg0, String arg1){ ... } }9. Java 呼叫 C++ 時傳遞矩陣 :
i. JAVA 檔案如下 :
package com.appmaster; import org.cocos2dx.lib.Cocos2dxActivity; import android.app.Activity; public class AMCocos2dxInterface { private static native void nativeLoginHandler(int[] array); ... static public void run(){ int[] array ={9, 5, 2, 7}; nativeLoginHandler(array); } }ii. C++ 檔案如下 :
#include "cocos2d.h" #include <jni/JniHelper.h> #include <jni.h> ... extern "C" { void Java_com_appmaster_AMCocos2dxInterface_nativeLoginHandler(JNIEnv* env, jobject thiz, jintArray ptr) { jsize length =env->GetArrayLength(ptr); if (length>0){ jint* intarr =env->GetIntArrayElements(ptr, 0); for (int i=0;i<length;++i){ printf("val[%d] =%d", i, intarr[i]); } env->ReleaseIntArrayElements(ptr, intarr, 0); } } ... }10. C++ 呼叫 Java 時傳遞矩陣 :
i. C++ 檔案如下 :
#include "cocos2d.h" #include <jni/JniHelper.h> #include <jni.h> ... int* praw_int =new int[4]; praw_int[0] =9; praw_int[1] =5; praw_int[2] =2; praw_int[3] =7; jintArray arrdata =env->NewIntArray(4); env->SetIntArrayRegion(arrdata, 0, 4, (jint*)praw_int); ... JNIEnv *env =NULL; jclass classid; jmethodID methodid; JavaVM* jvm = cocos2d::JniHelper::getJavaVM(); if (NULL == jvm) { return; } //setup env jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4); if (ret !=JNI_OK) { env =NULL; return; } classid =env->FindClass("com/appmaster/AMCocos2dxInterface"); if (!classid){ return; } methodid =env->GetStaticMethodID(classid, "initGameBarLib", "([II)V"); if (!methodid){ return; } env->CallStaticObjectMethod(classid, methodid, arrdata, 4); delete [] praw_int; }ii. JAVA 檔案如下 :
package com.appmaster; import org.cocos2dx.lib.Cocos2dxActivity; import android.app.Activity; public class AMCocos2dxInterface { static public void initGameBarLib(int[] data, int num){ ... } }11. Java 呼叫 C++ 時傳遞回呼函數 :
i. JAVA 檔案如下 :
package com.appmaster; import org.cocos2dx.lib.Cocos2dxActivity; import android.app.Activity; public class AMCocos2dxInterface { //傳遞回呼函數名稱 (字串) private static native void nativeAsyncMethod(final string funcString); ... static public void callbackFunc(){ //i will be callback from c++ } static public void run(){ nativeAsyncMethod("callbackFunc"); } }ii. C++ 檔案如下 :
#include "cocos2d.h" #include <jni/JniHelper.h> #include <jni.h> ... extern "C" { void Java_com_appmaster_AMCocos2dxInterface_ nativeAsyncMethod(JNIEnv* env, jobject thiz, jstring funcString) { const char* pFuncString =env->GetStringUTFChars(funcString, 0); ... //callback JNIEnv *env =NULL; jclass classid; jmethodID methodid; JavaVM* jvm = cocos2d::JniHelper::getJavaVM(); if (NULL == jvm) { env->ReleaseStringUTFChars(funcString, pFuncString); return; } //setup env jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4); if (ret !=JNI_OK) { env =NULL; env->ReleaseStringUTFChars(funcString, pFuncString); return; } classid =env->FindClass("com/appmaster/AMCocos2dxInterface"); if (!classid){ env->ReleaseStringUTFChars(funcString, pFuncString); return; } methodid =env->GetStaticMethodID(classid, pFuncString, "()V"); if (!methodid){ env->ReleaseStringUTFChars(funcString, pFuncString); return; } env->CallStaticObjectMethod(classid, methodid); env->ReleaseStringUTFChars(funcString, pFuncString); } ... }12. C++ 呼叫 Java 時傳遞回呼函數 :
(ps. 底下的實作並未真正的把 C function pointer 傳遞到 java 環境)
i. C++ (AMGamebarUtil.h)檔案如下 :
#include "cocos2d.h" ... //定義回呼函數 typedef void (*onLoginCallback)(const cocos2d::CCString* pStrAccountID, const cocos2d::CCString* pStrNickname); class AMGamebarUtil { public: static void initGameBarLib(onLoginCallback pCBFunc1); } ...i. C++ (AMGamebarUtil.cpp)檔案如下 :
#include <jni/JniHelper.h> #include <jni.h> #include "AMGamebarUtil.h" ... onLoginCallback pLC =NULL; //預先建立 function 讓 java 回呼 extern "C" { void Java_com_appmaster_AMCocos2dxInterface_nativeLoginHandler(JNIEnv* env, jobject thiz, jstring aid, jstring nickname) { const char* pAid =env->GetStringUTFChars(aid, 0); const char* pNick =env->GetStringUTFChars(nickname, 0); //若是回呼函數已指定則回呼之 if (pLC !=NULL){ pLC( cocos2d::CCString::createWithFormat("%s", pAid), cocos2d::CCString::createWithFormat("%s", pNick) ); } env->ReleaseStringUTFChars(aid, pAid); env->ReleaseStringUTFChars(nickname, pNick); } } void AMGamebarUtil::initGameBarLib(onLoginCallback pCBFunc1) { //呼叫 JAVA JNIEnv *env =NULL; jclass classid; jmethodID methodid; JavaVM* jvm = cocos2d::JniHelper::getJavaVM(); if (NULL == jvm) { CCLOG("Unity - AMGamebarUtil.cpp, Failed to get JNIEnv. JniHelper::getJavaVM() is NULL"); return; } //setup env jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4); if (ret !=JNI_OK) { env =NULL; return; } if (env ==NULL){ return; } classid =env->FindClass("com/appmaster/AMCocos2dxInterface"); if (!classid){ return; } methodid =env->GetStaticMethodID(classid, "initGameBarLib", "()V"); if (!methodid){ return; } //REGISTER CALLBACK FUNCTION pLC =pCBFunc1; //CALLING METHOD env->CallStaticObjectMethod(classid, methodid); }i. C++ (.cpp)執行如下 :
//實作回呼函數 void onLoginCallbackHandler(const cocos2d::CCString* pStrAccountID, const cocos2d::CCString* pStrNickname) { CCLOG("onLoginCallbackHandler(), aid=%s, nickname=%s", pStrAccountID->getCString(), pStrNickname->getCString()); } ... //實際呼叫 initGameBarLib 並傳遞回呼函數指標 AMGamebarUtil::initGameBarLib(&onLoginCallbackHandler);ii. JAVA 檔案如下 :
public class AMCocos2dxInterface { //預先定義回呼之 c++ method private static native void nativeLoginHandler(final String aid, final String nickname); static public void initGameBarLib(){ ... //回呼 c++ method nativeLoginHandler("THIS_IS_AID", "THIS_IS_NICKNAME"); } ... }
ref:http://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
ref:http://stackoverflow.com/questions/1232236/retrieving-byte-array-of-unknow-length-from-java-store
ref:http://www.lyceemermoz.com/iris/jlp/util/java/jdk/graphic/graphic.cpp
ref:http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/types.html
0 意見 :
張貼留言