總結關於lua, c , android,在 cocos2d-x 之間的調用方法


把這幾天瞎搞的東西總結一下. 

環境配置什么的也比較煩. ndk.java.在cocos2dx的環境中都有配置.參1

很基礎很基礎很基礎的環境配置. 

1.android與C 之間的調用

 android通過JNI 來調用C(不帶C++玩.extern "C"),

 1.1android調用C

  如果要在Eclipse中用C/C++編譯要在工程上選android tools 的add native support,來編譯c/c++.對於cocos2dx的理論上已經設置好了. 當然如果沒有. 那還是用cocos compile來編吧. 自己做的darkc項目的工程如果加上后會有問題. 可能是配置的原因 . 留個坑....

  在src下com.example.wifiip包MainActivity.java文件中聲明C方法: native public void onBtnClick();

  可以選擇用javah來把頭c的頭文件編譯出來,里面會有固定格式的函數聲明.

  Run->Extern tools

 

嗯 , 具體 的參數 作用 不明.  留坑 ....后面還要用的javap用於簽名java函數.用於jni層c call java.如果明白規則 也可不用.主要是為了明確descriptor 同上

 1 /* DO NOT EDIT THIS FILE - it is machine generated */
 2 #include <jni.h>
 3 /* Header for class com_example_wifiip_MainActivity */
 4 
 5 #ifndef _Included_com_example_wifiip_MainActivity
 6 #define _Included_com_example_wifiip_MainActivity
 7 #ifdef __cplusplus
 8 extern "C" {
 9 #endif
10 /*
11  * Class:     com_example_wifiip_MainActivity
12  * Method:    onBtnClick
13  * Signature: ()V
14  */
15 JNIEXPORT void JNICALL Java_com_example_wifiip_MainActivity_onBtnClick
16   (JNIEnv *, jobject);
17 
18 #ifdef __cplusplus
19 }
20 #endif
21 #endif

  函數明是有規則的. 對照上面那個java文件,如果知道規則也可以不用生成.直接在寫個定義

  在cpp文件中完成實現代碼.

  android.mk文件中入相關的編譯文件和頭文件以及相應的指令. 參2 

  然后編譯跑就行了. 在java代碼中要調用 

  

       static {
            System.loadLibrary("wifiIP");
        }

  總是忘記....

  其實不太難

 1.2 c call java 

  只要在jni層的c/c++代碼中加入相應的代碼就可以了

  調用靜態函數

    // 獲取 MainActivity類,不是對象,對象已經有了是:objActivity
    jclass clsActivity     = pJniEnv->FindClass("com/example/wifiip/MainActivity");
    /// 獲取類中的函數 getWifiAddress的函數ID,第三個參數填寫該函數的函數簽名
    jmethodID    method     = pJniEnv->GetMethodID(clsActivity, "getWifiAddress", "()I");
    /// 調用java層函數
    jobject object = pJniEnv->NewLocalRef(pJobject);
    int nIp = pJniEnv->CallIntMethod(object, method);

  非靜態函數

  

    long status;
       jclass cls;
       jmethodID mid;
       jint square;
       jboolean not;
       jobject jobj;
  cls = (*env)->FindClass(env, "com/example/hellojni/HelloJni");
   if(cls !=0)
   {

  jmethodID construction_id = (*env)->GetMethodID(env, cls, "<init>", "()V");

   if (construction_id ==0) {
     __android_log_print(ANDROID_LOG_INFO, "pvvvvvv_printStringJNi", "Result of construction_id== 0");
   }

  jobject mTestProvider = (*env)->NewObject(env, cls, construction_id);       mid = (*env)->GetMethodID(env, cls, "doLogin", "(ZZ)I");
  if(mid !=0)
  {
  square = (*env)->CallIntMethod(env, mTestProvider, mid, JNI_TRUE, JNI_TRUE);
   __android_log_print(ANDROID_LOG_INFO, "pvvvvvv_printStringJNi ","doLogin %d" ,square);
        }
    }

   這里有一個問題在於調用的android中的界面線程時要小心. 在調用的相關函數中Context context, 這個參數不能再傳this. 這地方坑我好久.因為實際上這里你是從外面調入. 不在一個線程中.就是空,  完全 不知道 你是誰啊.this毛線. 寫個靜態的存起this來或是傳入都可以. 

  實驗例子是:HelloJni. 

 

2.lua與C 之間的調用

   參3. 寫的十分詳細. 我就簡單寫下吧. 參4

  c 與 lua 是利用棧 來交互的. 純C環境下的也實現. 都是基於cocos下的. 不用自己搞 環境 - -!

  在cocos環境 lua調用C 需要把c函數注冊進lua中. 

auto engine = LuaEngine::getInstance();
ScriptEngineManager::getInstance()->setScriptEngine(engine);
 
LuaStack* stack = engine->getLuaStack();
stack->setXXTEAKeyAndSign("2dxLua", strlen("2dxLua"), "XXTEA", strlen("XXTEA"));

lua_State *L = stack->getLuaState();
 
lua_register(L, "test_lua_bind", test_lua_bind);

  

  也可以通過ScriptEngineManager類從頭取得當前的LuaEngine對象,然后再getLuaStack()方法  得到封裝的LuaStack對象,再調用getLuaState()得到原始的lua_State結構指針。只要知道了入  口位置,其他一切就不成問題了,還是挺簡單的。

  感興趣的話可以去看一下ScriptEngineManager類的詳細定義,在frameworks/cocos2d-     x/cocos/base/CCScriptSupport.h文件中。

  這個是直接注冊成一個全局函數 , 實際在dark工程中是注冊進名字空間中. 具體見工程....

  2.2 c++調用lua 

 lua_State* pL = lua_open();  
    luaopen_base(pL);  
  
    /* 執行腳本 */  
    luaL_dofile(pL, "helloLua.lua");  
  
    /* 把helloAdd函數對象放到棧中 */  
    lua_getglobal(pL, "helloAdd");  
  
    /* 把函數所需要的參數入棧 */  
    lua_pushnumber(pL, 10);  
    lua_pushnumber(pL, 5);  
  
    /*  
        執行函數,第一個參數表示函數的參數個數,第二個參數表示函數返回值個數 , 
        Lua會先去堆棧取出參數,然后再取出函數對象,開始執行函數 
    */  
    lua_call(pL, 2, 1);  
  
    int iResult = lua_tonumber(pL, -1);  

  依然是利用棧的方式 . 

  在cocos 環境下簡單的好多.

  寫一個全局的方法. 

    auto luaStack = cocos2d::LuaEngine::getInstance()->getLuaStack();
    lua_State* L = luaStack->getLuaState();
    lua_getglobal(L, "onSdkInitCallBack");       /* query function by name, stack: function */
    if (!lua_isfunction(L, -1))
    {
        CCLOG("[LUA ERROR] name '%s' does not represent a Lua function", "onSdkInitCallBack");
        lua_pop(L, 1);
        return;
    }
    luaStack->executeFunction(0);

  

3.android與lua之間的調用.

   本來理解 lua 需要先調

  static public void showAlertDialog(final String title,
            final String message, final int luaCallbackFunction) {
        s_instance.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                
                doSdkLogin(false, true);
                
                
                AlertDialog alertDialog = new AlertDialog.Builder(s_instance).create();
                alertDialog.setTitle(title);
                alertDialog.setMessage(message);
                alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        s_instance.runOnGLThread(new Runnable() {
                            @Override
                            public void run() {
                                Cocos2dxLuaJavaBridge.callLuaFunctionWithString(luaCallbackFunction, "xxxCLICKEDvvvxxx");
                                Cocos2dxLuaJavaBridge.releaseLuaFunction(luaCallbackFunction);
                            }
                        });
                    }
                });
                alertDialog.setIcon(R.drawable.icon);
                alertDialog.show();
            }
        });
    }

 

用 c.再通過jni調用java 實際上這東西 已經在cocos下集成好了.luaj直接使用就可以了. 想想全是眼淚....

  注意 GL線程. 和ui線程 之間的使用

  

4.cocos2d-x 3.0下綁定lua

   綁定類進 參3里寫的很詳細....... 實在沒啥可總結的.  實際項目只是注冊函數進實現在. 一會818看有沒有他們自己注冊進去的類.

   

參考

1. http://jingyan.baidu.com/article/3ea51489e7a9bd52e61bbac7.html

2. http://blog.csdn.net/yili_xie/article/details/4906865

3. http://cn.cocos2d-x.org/tutorial/show?id=1295

4. http://blog.csdn.net/musicvs/article/details/8440707

5. http://blog.csdn.net/xdw1985829/article/details/6900155

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM