Cocos2dx 3.0下的C/C++和Lua通讯以及Object C与Lua通讯

网上关于Cocos2dx开发过程中Lua的使用以及原理教程已经很多了,结合我的开发经验,我在这里稍微整理下。

可以说Cocos2dx-Lua提供了一种很轻便的开发模式,省去了冗长的编译时间,同时让热更成为了很容易的一件事情,不仅仅是在Android上,iOS上也轻易绕开了官方的审查,毕竟Lua在iOS系统看来都只是资源,就像txt文档。

然而Cocos2d-x是用C++开发的,那么,Lua究竟是怎么和C++通信的呢?在发布iOS平台的时候Lua有时候又需要和Object C交互,又应该怎么处理呢?

C/C++和Lua的通讯是通过维护一个Lua堆栈和Lua全局表进行的。Lua堆栈也是满足堆栈先进后出的特性,同时也支持使用索引进行访问,索引方式可以是正数也可以是负数,索引正数1表示栈底,索引负数-1表示栈顶。Lua启动或调用C语言时,Lua堆栈至少会有20个空闲槽位。Lua堆栈不是一个全局性的结构,每个函数都有自己的局部私有堆栈,当Lua调用C/C++函数的时候第一个参数总是这个局部栈的索引1。当C/C++函数把返回值压入Lua堆栈之后,该栈会被自动清空。

Lua堆栈
3               栈顶               -1
2                                     -2
1               栈底               -3

Lua全局表是一个类似于Map哈希表的结构,可以通过Key读取到对应的Value,比如Lua中定义有一个变量:

id = 10086

这就相当于在Lua全局表中存放了一个Key为'id',Value为‘10086’的映射关系,之后我们可以通过Key在Lua全局表中查到对应的Value‘10086’。

那么C\C++和Lua拥有不同的数据类型,要实现两者之间的数据通信该怎么办?Lua虚拟机提供Lua_State这样一种数据结构。任何一种数据从C\C++传入Lua虚拟机中,Lua都会将这类数据转换为一种通用的结构lua_TValue,并且将数据复制一份,将其压入Lua堆栈中。在Lua中,number、boolean、nil、light userdata四种类型的值是直接存在栈上元素里的,和Lua的垃圾回收无关,string、table、closure、userdata、hread存在栈上元素里的只是指针,他们都会在生命周期结束后被Lua垃圾回收。Lua有自己的GC,C\C++由自己申请和释放内存,所以两者之间的内存管理是独立的。从C\C++中传递数据到Lua虚拟机会发生数据拷贝,从Lua虚拟机中传递出来是直接从虚拟栈中取值或者地址,所以数据从虚拟栈中pop之后,是否依然是有效引用需要额外注意。

了解了上面的基础知识之后,接下来了解下Lua提供了哪些C API来对Lua堆栈进行操作,以实现C\C++和Lua的通讯。首先了解下操作Lua堆栈的基本步骤,主要有一下几步:

  1. 创建Lua实例:luaL_newstate();
  2. 加载Lua文件:luaL_loadfile(L,"hello.lua");
  3. 运行Lua文件:lua_pcall(L,参数个数,返回值个数,错误处理函数索引);
  4. 操作Lua堆栈:(参考Lua 5.1 参考手册
lua_getglobal(L,“name”) 把全局变量name压入堆栈
lua_setglobal(L,“name”) 从堆栈上弹出一个值并将其设置到全局变量name中
lua_getfield(L,index,“key”) 把t[key]的值压入栈,t是有效索引 index 指向的值
lua_gettable(L,index) 把value出栈并把t[value]值压入栈,t是有效索引 index 指向的值,value是栈顶存放的值
lua_tonumber(L,index) 把有效索引 index 指向的栈值转换成C类型的lua_Number值
lua_tostring(L,index) 把有效索引 index 指向的栈值转换成C字符串
lua_pushnumber(L,num) 把数字num压栈
lua_pushstring(L,str) 把指针str指向的以零结尾的字符串做一次内存拷
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值