cocos2dx java 调用lua_总结关于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

cf1e811d1ab0214085fecc8ebd19305b.png

嗯 , 具体 的参数 作用 不明. 留坑 ....后面还要用的javap用于签名java函数.用于jni层c call java.如果明白规则 也可不用.主要是为了明确descriptor 同上

1 /*DO NOT EDIT THIS FILE - it is machine generated*/

2 #include

3 /*Header for class com_example_wifiip_MainActivity*/

4

5 #ifndef _Included_com_example_wifiip_MainActivity6 #define _Included_com_example_wifiip_MainActivity

7 #ifdef __cplusplus8 extern "C"{9 #endif

10 /*

11 * Class: com_example_wifiip_MainActivity12 * Method: onBtnClick13 * Signature: ()V14 */

15 JNIEXPORT voidJNICALL Java_com_example_wifiip_MainActivity_onBtnClick16 (JNIEnv *, jobject);17

18 #ifdef __cplusplus19 }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);

非静态函数

longstatus;

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, "", "()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(finalString title,final String message, final intluaCallbackFunction) {

s_instance.runOnUiThread(newRunnable() {

@Overridepublic voidrun() {

doSdkLogin(false, true);

AlertDialog alertDialog= newAlertDialog.Builder(s_instance).create();

alertDialog.setTitle(title);

alertDialog.setMessage(message);

alertDialog.setButton("OK", newDialogInterface.OnClickListener() {

@Overridepublic void onClick(DialogInterface dialog, intwhich) {

s_instance.runOnGLThread(newRunnable() {

@Overridepublic voidrun() {

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看有没有他们自己注册进去的类.

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值