首页 > 代码库 > 总结关于lua, c , android,在 cocos2d-x 之间的调用方法

总结关于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 #endif10 /*11  * Class:     com_example_wifiip_MainActivity12  * Method:    onBtnClick13  * Signature: ()V14  */15 JNIEXPORT void JNICALL Java_com_example_wifiip_MainActivity_onBtnClick16   (JNIEnv *, jobject);17 18 #ifdef __cplusplus19 }20 #endif21 #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

 

总结关于lua, c , android,在 cocos2d-x 之间的调用方法