cocos lua绑定感悟---tolua_isusertable及lua如何访问cocos静态函数的方法
2015-08-19 17:19
821 查看
现在还是个新手,对很多还不是很了解,所以语言估计会有点晦涩,望原谅啊!!
代码的意思很简单,无非就是判断栈中 loc位置的数据是不是usertable。代码大概的思路就是从栈的loc位置取出值A,来在注册表中找到值B,然后对B进行字符串比较判断是不是type类型或者const type类型。所以很明显A就是type或者const type对应的table。那什么时候会调用tolua_isusertable呢?
索性就搜索一下tolua_isusertable 到底被哪里引用到了。看到基本上都是create方法中引用了,还有一些其他的方法,仔细观察这些函数,发现都是静态函数,所以就猜测 是不是静态函数在生成 lua 和cocos中间层代码的时候会被生成?我带着疑问就在自定义类中也定义了个静态方法,发现果然生成了tolua_isusertable。
静态方法可以通过类来调用,所以在执行之前要判断lua传递过来的是不是该类的类型。这就是tolua_isusertable的作用。而其它的成员函数是判断传递过来的是不是userdata,并且该userdata是不是该类的类型 。
举个例子吧:
这里ccc.MyClass就是个table,是传递到cocos的loc位置的数据,create在C++的MyClass 中是静态函数。
总结:tolua_isusertable用在lua直接通过表(C++的类)来调用的函数中,判断这个表是不是对应的C++类型。而tolua_isuserdata用在通过对象调用的函数中。
那么问题来了,我可以通过lua变量来访问静态函数么?我试了下,发现不行也是坑爹货。
程序崩溃。。。
那就没有办法来解决这个问题吗?其实要改的话,也挺简单。先贴下getData的中间代码吧:
程序就是在这里崩溃的,tolua发现传递过来的不是个table,其实它是个userdata,所以报错啦!!我们改的也是这里,加个判断是否是userdata就可以了嘛!!
将那行改成:
搞定啦!!
<pre name="code" class="html">TOLUA_API int tolua_isusertable (lua_State* L, int lo, const char* type, int def, tolua_Error* err) { if (def && lua_gettop(L)<abs(lo)) return 1; if (lua_isusertable(L,lo,type)) return 1; err->index = lo; err->array = 0; err->type = type; return 0; }
static int lua_isusertable (lua_State* L, int lo, const char* type) { int r = 0; if (lo < 0) lo = lua_gettop(L)+lo+1; lua_pushvalue(L,lo); lua_rawget(L,LUA_REGISTRYINDEX); /* get registry[t] */ if (lua_isstring(L,-1)) { r = strcmp(lua_tostring(L,-1),type)==0; if (!r) { /* try const */ lua_pushstring(L,"const "); lua_insert(L,-2); lua_concat(L,2); r = lua_isstring(L,-1) && strcmp(lua_tostring(L,-1),type)==0; } } lua_pop(L, 1); return r; }
代码的意思很简单,无非就是判断栈中 loc位置的数据是不是usertable。代码大概的思路就是从栈的loc位置取出值A,来在注册表中找到值B,然后对B进行字符串比较判断是不是type类型或者const type类型。所以很明显A就是type或者const type对应的table。那什么时候会调用tolua_isusertable呢?
索性就搜索一下tolua_isusertable 到底被哪里引用到了。看到基本上都是create方法中引用了,还有一些其他的方法,仔细观察这些函数,发现都是静态函数,所以就猜测 是不是静态函数在生成 lua 和cocos中间层代码的时候会被生成?我带着疑问就在自定义类中也定义了个静态方法,发现果然生成了tolua_isusertable。
静态方法可以通过类来调用,所以在执行之前要判断lua传递过来的是不是该类的类型。这就是tolua_isusertable的作用。而其它的成员函数是判断传递过来的是不是userdata,并且该userdata是不是该类的类型 。
举个例子吧:
<span style="font-family:KaiTi_GB2312;font-size:14px;">local test = ccc.MyClass:create()</span>
这里ccc.MyClass就是个table,是传递到cocos的loc位置的数据,create在C++的MyClass 中是静态函数。
总结:tolua_isusertable用在lua直接通过表(C++的类)来调用的函数中,判断这个表是不是对应的C++类型。而tolua_isuserdata用在通过对象调用的函数中。
那么问题来了,我可以通过lua变量来访问静态函数么?我试了下,发现不行也是坑爹货。
<pre name="code" class="html">local test = ccc.MyClass:create() print("the first cocos bind lua result "..test:foo(2)) print(test:getData())
程序崩溃。。。
那就没有办法来解决这个问题吗?其实要改的话,也挺简单。先贴下getData的中间代码吧:
<pre name="code" class="html">int lua_myclass_MyClass_getData(lua_State* tolua_S) { int argc = 0; bool ok = true; #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; #endif #if COCOS2D_DEBUG >= 1 if (!tolua_isusertable(tolua_S,1,"gls.MyClass",0,&tolua_err))) goto tolua_lerror; #endif argc = lua_gettop(tolua_S) - 1; if (argc == 0) { if(!ok) return 0; int ret = GameLogic::MyClass::getData(); tolua_pushnumber(tolua_S,(lua_Number)ret); return 1; } CCLOG("%s has wrong number of arguments: %d, was expecting %d\n ", "getData",argc, 0); return 0; #if COCOS2D_DEBUG >= 1 tolua_lerror: tolua_error(tolua_S,"#ferror in function 'lua_myclass_MyClass_getData'.",&tolua_err); #endif return 0; }
if (!tolua_isusertable(tolua_S,1,"gls.MyClass",0,&tolua_err))) goto tolua_lerror;
程序就是在这里崩溃的,tolua发现传递过来的不是个table,其实它是个userdata,所以报错啦!!我们改的也是这里,加个判断是否是userdata就可以了嘛!!
将那行改成:
if (!tolua_isusertable(tolua_S,1,"gls.MyClass",0,&tolua_err) && !tolua_isusertype(tolua_S,1,"gls.MyClass",0,&tolua_err)) goto tolua_lerror;
搞定啦!!
相关文章推荐
- 4、Cocos2dx 3.0三,找一个小游戏开发Hello World 分析
- Cocos从入门到精通--《Cocos引擎在Windows平台上的搭建》
- cocos2d js 使用 cocos studio 生成的合图
- cocos2dx接入微信分享(IOS)
- 【存储】Cocos2d-x将资源目录(Assets)文件拷贝到可写目录
- cocos2dx3.4mac环境搭建
- 从CCObject看Cocos2d-x的拷贝机制
- Cocos从入门到精通--《Cocos引擎在mac平台上的搭建》
- 1.cocos2dx它Menu(CCMenuItemFont,CCMenuItemImage,CCMenuItemLabel,CCMenuItemSprite,CCMenuItemToggle)
- 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第四节:3D公告板
- cocos2d-x3.2 在Windows下打包Android平台APK
- 小小菜之Cocos2d-x游戏开发旅程——常用Action(1)
- Cocos2D游戏之旅(五):三种方法实现技能动画
- Cocos2d-x 3.x 编译Android方法
- cocos2d-x 3.6运行cocos run出现Ndk build failed解决办法
- cocos2d-x开发日志10 ——贪食蛇源码
- cocos2d-x开发日志09 —— Vector
- cocos2d-x开发日志08 —— 绘图工具
- 【Cocos2dx】Windows平台下Cocos2dx 2.x的下载、安装、配置,打造自己的Helloworld
- cocos-2dx 渲染(2)