• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

把这几天瞎搞的东西总结一下. 

环境配置什么的也比较烦. 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

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap