1、lua虚拟机和C++相互调用、lua设计基础的相关博客,供以后复习:
http://cn.cocos2d-x.org/tutorial/show?id=1474
http://blog.csdn.net/ym012/article/details/7209637
http://www.cnblogs.com/sifenkesi/p/3876745.html
http://my.oschina.net/xlplbo/blog/314956
http://blog.csdn.net/dongdongdongjl/article/details/8629704
2、本人的环境文档:链接:http://pan.baidu.com/s/1o6FROMY 密码:o7vt
或者:https://github.com/wjingzhe/LuaCppSrc
直接使用源码配置。luac.c和lua.c相关说明参照:
http://blog.csdn.net/dongdongdongjl/article/details/8629704
3、分析文章待续,先熟悉lua机的源码。cocos2d-x中,添加C++和luaScript的桥接函数,比如:
int lua_cocos2dx_3d_Skeleton3D_getBoneByName(lua_State* tolua_S)
{
int argc = 0;
cocos2d::Skeleton3D* cobj = nullptr;
bool ok = true;
#if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
#endif
#if COCOS2D_DEBUG >= 1
if (!tolua_isusertype(tolua_S,1,"cc.Skeleton3D",0,&tolua_err)) goto tolua_lerror;
#endif
cobj = (cocos2d::Skeleton3D*)tolua_tousertype(tolua_S,1,0);
#if COCOS2D_DEBUG >= 1
if (!cobj)
{
tolua_error(tolua_S,"invalid ‘cobj‘ in function ‘lua_cocos2dx_3d_Skeleton3D_getBoneByName‘", nullptr);
return 0;
}
#endif
argc = lua_gettop(tolua_S)-1;
if (argc == 1)
{
std::string arg0;
ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.Skeleton3D:getBoneByName");
if(!ok)
{
tolua_error(tolua_S,"invalid arguments in function ‘lua_cocos2dx_3d_Skeleton3D_getBoneByName‘", nullptr);
return 0;
}
cocos2d::Bone3D* ret = cobj->getBoneByName(arg0);
object_to_luaval<cocos2d::Bone3D>(tolua_S, "cc.Bone3D",(cocos2d::Bone3D*)ret);
return 1;
}
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.Skeleton3D:getBoneByName",argc, 1);
return 0;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function ‘lua_cocos2dx_3d_Skeleton3D_getBoneByName‘.",&tolua_err);
#endif
return 0;
}
4、前几天面试遗留:
1)lua的table本身是由两块内存组成,一块是连续的array,另外一块则是hashTable实现的。因为没看过源码不确认数组这块的存储,就没有提及
2)lua的调用栈从1到N为栈增加,即从栈底向栈顶进发。-1为栈顶,-N为栈底。具体的内存结构还没看
3)QuickSort和HeapSort的确切代码,主要在于QuickSort的非递归实现。非递归没真正实现过了,今晚处理一下。
4)认真考究cocos2d的主线线程流程,有利于以后做架构优化
5、lua脚本调用C++,则是先压函数地址为0下标位;C++、lua入栈从左参数开始入栈。C++若调用lua的函数则需要使用lua_call;Lua只能调用使用特定格式的函数:
定义一个C/C++函数:
代码:typedef int (*lua_CFunction) (lua_State *L); //要求参数和返回值必须和这个一直,即可以赋值函数指针给lua_CFunction的都可以被调用
函数必须以Lua解释器作为参数,并且返回值为int类型。既然Lua解释器作为函数的参数,那么实际上函数可以从栈中取得任意多个参数。下面我 们将看到,返回的整数值代表入栈的值的数目。如果有一个C/C++函数,你想在Lua中调用他,很容易封装一下就可以满足上述要求。
6、上面一条成为C++粘合层,cocos2d-lua的分支就是增加了粘合层来建立lua虚拟机和C++库的连接,同时删减没必要了模块。这个粘合层在设计模式中叫做代理,早前云风曾经提到是否使用类似的设计,如果真要提供库,必须减少粘合层的厚度才能保证健壮性
lua这边的库也要实现Lua的粘合层,才能使得脚本开发时使用的是和C++类似的API。
cocos的粘合层需要重新编写一边,这也是为什么自定义库需要使用luabinding等工具方便。而维护引擎必须也要熟悉cocos接口设计思想,如第3条,都会根据参数个数去实现粘合调用的是哪个接口,quick引擎组要做的事情大部分是这个吧。