Lua与C交互之基础操作(1)
@(语言)
Lua是一个嵌入式的语言,可以Lua可以作为程序库用来扩展应用的功能,也可以注册有其他语言实现的函数,这些函数可能由C语言(或其他语言)实现,可以增加一些不容易由Lua实现的功能。这就是Lua这几年在收集游戏开发领域飞速的发展使用的原因,便于热更新,尤其使在IOS平台上。这篇文章主要是自己在学习过程中的一些记录,主要参考<Lua程序设计>一书第二版。
1. 交互栈
在使用过程中,虽然在游戏中我们把lua作为脚本来用,这几年手机游戏其实大量的逻辑都在lua上进行,包括战斗逻辑。尽管如此,使用过程中都会涉及到Lua和其他语言之间的互相调用。在C和Lua之间通信关键内容在于一个虚拟的栈。
栈是一个严格FIFO规则,每条记录可以是任何类型。而几乎所有的API调用都是对栈上的值进行操作,所有C与Lua之间的数据交换也都通过这个栈来完成,也可以使用栈来保存临时变量。栈的使用解决了C和Lua之间两个不协调的问题:第一,Lua会自动进行垃圾收集,而C要求显示的分配存储单元,两者引起的矛盾。第二,Lua中的动态类型和C中的静态类型不一致引起的混乱。
栈中的每一条记录都可以保存任何 Lua 值。当你想要从 Lua 请求一个值时,Lua会将请求的值将会被压入栈。当你想要传递一个值给 Lua,首先将这个值压入栈,然后调用 Lua(这个值将被弹出)。
# 数据类型
可以参考Lua数据类型实现源码解析 一文, Lua包含值类型boolean、number、string、userdata、function、thread和table。实际在底层实现中可以根据下图理解。
索引
操作过程中基本都是对站定就行操作,栈的索引可以使用正索引或者负索引,即在不知道栈大小的情况下,正数索引1永远表示栈底,负数索引-1永远表示栈顶。
栈大小
luaconfig中是可以配置的(似乎)。默认是20,一般在函数操作过程中,需要维护栈的大小不会无限扩展下去,比如在函数调用后及时的清理。
2. 基本操作
压入栈
void lua_pushnil (lua_State *L);
void lua_pushboolean (lua_State *L, int bool);
void lua_pushnumber (lua_State *L, double n);
void lua_pushlstring (lua_State *L, const char *s, size_t length);
void lua_pushstring (lua_State *L, const char *s);
void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n);
查询元素
int lua_toboolean (lua_State *L, int index);
double lua_tonumber (lua_State *L, int index);
const char * lua_tostring (lua_State *L, int index);
size_t lua_strlen (lua_State *L, int index);
void *lua_touserdata(lua_State*L,intindex)
维护栈
//返回堆栈中的元素个数
int lua_gettop (lua_State *L);
//设置栈顶为一个指定的值,如果开始的栈顶高于新的栈顶,顶部的值被丢弃
void lua_settop (lua_State *L, int index);
//压入指定索引的一个抟贝到栈顶
void lua_pushvalue (lua_State *L, int index);
//移除指定索引位置的元素,上面的元素下移
void lua_remove (lua_State *L, int index);
//移动栈顶元素到指定索引的位置,其他元素上移
void lua_insert (lua_State *L, int index);
//从栈顶弹出元素值并将其设置到指定索引位置,没有任何移动
void lua_replace (lua_State *L, int index);
表操作
lua_getfield/lua_setfield
void lua_getfield (lua_State *L, int index , const char *k);
Pushes onto the stack the value t[k], where t is the value at the given valid index index 。
index 是table变量在栈中的索引值,k是table的键值,执行成功后将字段值压入栈中。
void lua_setfield (lua_State *L, int index, const char *k);
Does the equivalent to t[k] = v, where t is the value at the given valid index index and v is the value at the top of the stack,This function pops the value from the stack。
index 是table变量在栈中的索引值,k是table的键值,v为栈顶元素,执行成功后将栈顶元素弹出。
lua_getglobal /lua_setglobal
// #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
void lua_getglobal (lua_State *L, const char *name);
将全局表中s索引对应的元素压入栈
// #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s)
void lua_setglobal (lua_State *L, const char *name);
将栈顶赋值给全局中s索引对应的元素,并弹出栈顶
lua_gettable/lua_settable
void lua_gettable (lua_State *L, int index);
Pushes onto the stack the value t[k], where t is the value at the given valid index index and k is the value at the top of the stack. This function pops the key from the stack (putting the resulting value in its place).
把t[k] 值压入堆栈,这里的 t 是指有效索引 index 指向的值,而 k 则是栈顶放的值。这个函数会弹出堆栈上的 key,把结果放在栈上相同位置。
void lua_settable (lua_State *L, int index);
Does the equivalent to t[k] = v, where t is the value at the given valid index index, v is the value at the top of the stack, and k is the value just below the top.This function pops both the key and the value from the stack.ue from the stack.
作一个等价于 t[k] = v 的操作,index 是table变量在栈中的索引值,v 为栈顶的值, k 是栈顶之下的元素。执行成功后把键和值都从堆栈中弹出。
lua_rawset / lua_rawget
void lua_rawget (lua_State *L, int index);
void lua_rawset (lua_State *L, int index);
与 lua_gettable/lua_settable类似,不过不会操作metamethods, 操作的Key/Value都在栈顶,栈顶是Value,第二个是Key'
lua_rawgeti /lua_rawseti
void lua_rawgeti (lua_State *L, int index, int n);
void lua_rawseti (lua_State *L, int index, int n);
与lua_getfield/lua_setfield类似,不过不会操作metamethods
lua_rawgeti 相当于:
lua_pushnumber(L, key); lua_rawget(L, t);
lua_rawseti 相当于:lua_pushnumber(L, key); lua_insert(L, -2); lua_rawset(L, t);
int luaL_getmetafield (lua_State *L, int obj, const char *e);
Pushes onto the stack the field e from the metatable of the object at index obj. If the object does not have a metatable, or if the metatable does not have this field, returns 0 and pushes nothing.
结束
表操作其实有很多可以介绍,尤其是涉及到metatable这块,后续补充。
Lua与C交互之基础操作(1)的更多相关文章
- Lua 和 C 交互中虚拟栈的操作
Lua 和 C 交互中虚拟栈的操作 /* int lua_pcall(lua_State *L, int nargs, int nresults, int msgh) * 以保护模式调用具有" ...
- Lua和C++交互 学习记录之二:栈操作
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...
- 用好lua+unity,让性能飞起来——lua与c#交互篇
前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ...
- Lua和C++交互详细总结
转自:http://cn.cocos2d-x.org/tutorial/show?id=1474 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信 ...
- Lua与C++交互初探之Lua调用C++
Lua与C++交互初探之Lua调用C++ 上一篇我们已经成功将Lua的运行环境搭建了起来,也成功在C++里调用了Lua函数.今天我来讲解一下如何在Lua里调用C++函数. Lua作为一个轻量级脚本语言 ...
- SLAM+语音机器人DIY系列:(一)Linux基础——3.Linux命令行基础操作
摘要 由于机器人SLAM.自动导航.语音交互这一系列算法都在机器人操作系统ROS中有很好的支持,所以后续的章节中都会使用ROS来组织构建代码:而ROS又是安装在Linux发行版ubuntu系统之上的, ...
- Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...
- Lua和C++交互 学习记录之八:C++类注册为Lua模块
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...
- Lua和C++交互 学习记录之七:C++全局函数注册为Lua模块
主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3 参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...
随机推荐
- jq通过对象获取其ID值
$(this).click(function(){ var this_id=$(this).attr("id");// attr(属性名) 获取属性的值 alert(this_id ...
- 从零开始学 Web 之 CSS(二)文本、标签、特性
大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识 ...
- SQL 必知必会·笔记<14>更新和删除数据
1. 更新数据 基本的UPDATE语句,由三部分组成: 要更新的表 列名和它们的新值 确定要更新那些行的过滤条件 更新单列示例: UPDATE Customers SET cust_email = ' ...
- RocketMQ系列实战
RocketMQ实战(一)RocketMQ实战(二)RocketMQ实战(三):分布式事务RocketMQ实战(四)
- NIO Channel和Buffer
Java NIO 由以下几个核心部分组成: Buffer Channel Selector 传统的IO操作面向数据流,意味着每次从流中读一个或多个字节,直至完成,数据没有被缓存在任何地方.NIO操作面 ...
- javascript的作用域和优先级
变量的作用域是在定义时决定的,不是在运行时活动对象是在运行时决定的?如果就创建一个对象,使用完毕就完了,就使用json字面量的方式如果对象被反复创建,反复使用,就使用自定义的构造函数方式优先级内部变量 ...
- Java提高篇之抽象类与接口
接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念 ...
- #14 Python模块
前言 前面的文章中,有许多地方都用到了Python的模块,这个到底是个什么神奇的东西呢?让我们来一起盘它! 一.什么是模块 在前几节中,我们已经接触了一些模块:math.random.time等,它们 ...
- GNU μC/OS-II 在 S3C2440 上中断的实现
上一篇文章介绍了S3c2440的中断体系结构,今天我们来分析一下GNU-uC/OS-II在S3c2440上中断的实现. 首先找到IRQ的中断的向量,位于 2440init.S : OK ,我们通过名字 ...
- 作用域public、private、protected、以及不写时的区别?
区别如下: 作用域 当前类 同包 子孙类 其他 public √ √ √ √ protected √ √ √ X default √ √ X X private √ X X ...