C++与Lua交互(三)
通过上一篇的热身,我们对C++调用lua变量有了一个认识,现在让我们再深入一点,去探索一下如何调用lua的函数、表。
Lua与宿主通讯的关键——栈
lua是个动态脚本语言,它的数据类型如何映射到C++这种静态类型语言中?lua是有GC机制的,这与C++手动管理内存相悖。如何解决这些问题呢?lua用一个抽象的栈与宿主语言交互,栈中的每一条记录都可以保存lua值。无论何时,我们想要从lua请求一个值,调用lua,被请求的值将会被压入栈。

栈是由lua来管理的,垃圾回收器知道哪个值正在被C使用(如果从lua中获得一个字符串char*时,我们需要自己备份一个,不然被lua回收后,我们保存的指针将会失效)。lua以一个严格的后进先出规则来操作栈,当我们调用lua时,它只会改变栈顶部分。我们的C代码有更多的自由,我们可以查询栈上的任何元素,甚至在任何一个地方插入和删除元素。
压栈API有如下:

查询栈中元素API:

其他的一些栈操作API:
调用lua函数
要调用一个函数,我们需要知道两个信息:函数的地址和函数的签名。如何获得lua中的指定函数的地址?很简单,与获得变量的地址一样,运用lua_getglobal(),第二个参数为lua函数的函数名。此时,该函数被压入栈顶了,如果存在的话。既然在栈顶了,那么我们可以使用lua_pcall()来调用栈顶的函数。代码如下:


运行之后,得到如下结果:
lua_pcall()这个API,我们之前已经接触过了,那是在读入文件、lua代码后,即luaL_load*()之后执行的操作。在这里,其后面的三个参数依然为0。后面三个参数到底有什么用呢?我们先来看一下lua文档:

lua_pcall()内部调用的是lua_call(),我们先来看看msgh这个参数,这个参数一般都设置为0,它只有在出错的时候才会有可能用到。我们的精力花在前两个参数上:nargs、nresults。

我来翻译一下:你必须遵守下面的协议来调用函数:首先,被调用的函数要被压入栈,该函数的参数要按照直接的顺序压入栈。第一个参数要第一个入栈,以此类推。最终你调用lua_call。nargs参数表示你压入栈中的参数个数。该函数及其所有的参数在被调用的时候都会从栈中弹出。函数的返回值将会在函数返回的时候压入栈中。返回值的个数用nresults这个参数来调整,除非传入的是LUA_MULTRET(注:即-1)。在这种情况下,函数的全部返回值都会入栈。lua会处理栈的空间,以使所有的返回值都有充足的栈空间。所有的返回值是以直接入栈的顺序压栈的(即第一返回值先入,依次类推),所以经过调用后,最后一个返回值在栈顶。
原来,nargs是表示传入参数个数,nresults指示返回参数个数。我们来写代码验证一下

我们在test.lua中定义了一个函数,该函数带有一个参数,两个返回值。我们先不管返回值,先关注其参数。根据说明,我们要先压入函数名,再压入参数。C++代码如下:

运行结果如下:

现在,我们来尝试获得返回值,根据lua函数的签名,我们指定两个返回值试试:

结果如下:

啊哈,是不是有种太简单了的感觉?你的感觉没错,就这么简单!根据文档,返回值的个数我们可以随意指定,如果感觉不过瘾,可以试试将返回值指定为1,-1,3。试试看有什么结果。
取得lua表数据
与调用lua函数不同的地方在于,这里我们使用lua的另一个API:lua_gettable()。我们先来看下文档:
翻译如下:将t[k]的值压入栈。t是栈中位于参数index所指向的位置,k为栈顶的值。此函数调用后,将会把栈顶的k的值出栈,将返回的结果放入栈顶。在lua中,这个调用将会触发metamethod的“index”事件。
根据描述,我们有如下代码:

结果如下:

至此,通过c++调用lua的各种数据的方式基本描述了一遍。接下来,我们要反客为主,用lua调用c++代码,这就有点纠结了,特别是调用c++ dll的时候。不过,u r lucky,我已经解决了问题,解决的方法已经在第一篇的代码中了。下一篇我我们一起来填坑。: )
总结
没啥总结。C++调用lua简单粗暴有用。值得一提的是,用sublime text写脚本,真是太舒服了!用它写lua、python爽快不止一点点。而且它还能用python扩展。强烈推荐大家写脚本的时候使用它。
C++与Lua交互(三)的更多相关文章
- C++与Lua交互之配置&交互原理&示例
|Lua 简介 Lua 是一种轻量小巧的脚本语言,也是号称性能最高的脚本语言,它用C语言编写并以源代码形式开放. 某些程序常常需要修改内容,而修改的内容不仅仅是数据,更要修改很多函数的行为. 而修改函 ...
- C++与Lua交互(四)
引言 通过前几篇,我们已经对Lua的C API有了一定的了解,如lua_push*.lua_is*.lua_to*等等.用C++调用Lua数据时,我们主要运用lua_getglobal与lua_pus ...
- C++与Lua交互(一)
引言 之前做手游项目时,客户端用lua做脚本,基本所有游戏逻辑都用它完成,玩起来有点不爽,感觉"太重"了.而我又比较偏服务端这边(仅有C++),所以热情不高.最近,加入了一个端游项 ...
- lua视频教程三套高清新
目录 1. 下载地址 2. 某网校 Lua 经典教程 3. lua脚本语言零基础开发教程19课全 4. LUA完整视频+Cocos2d-x项目实战 1. 下载地址 https://www.cnblog ...
- Win32下 Qt与Lua交互使用(三):在Lua脚本中connect Qt 对象
话接上文.笔者为了方便使用Lua,自己编写了一个Lua的类.主要代码如下: QLua.h #ifndef QLUA_H #define QLUA_H // own #include "inc ...
- C++与Lua交互(二)
上一篇我们搭建好了整个的项目环境,现在,我们一起探索一下如何将lua寄宿到C++中. 宿主的实现 我们在LuaWithCPPTest项目下,查看Source.cpp代码如下: #include < ...
- 最优雅的C++跟lua交互.
我先来吐槽一下我们这个项目. 我是做手机游戏的, cocos2dx引擎, lua编码. 这本来是一件很欢快的事情, 因为不用接触C++. C++写久了的人写lua, 就会感觉任督二脉被打通了, 代码写 ...
- C++与lua交互
项目开发的脚本层用的是Lua,引擎用的是C++.但是经理不给开放引擎层的代码.刚好最近项目空闲,安排了学习C++跟Lua的通信. 一.C++与Lua数据交互 数据交互主要是通过C API来实现 首先, ...
- 整理Lua和Unity和Lua交互文章链接
重点文章: 1.[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 2.[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(中) 3.Lua和C++交互详细总结 4. ...
随机推荐
- QT5 串口收发实例代码
以下代码是自己测试门禁系统使用的 主要用到了串口的接收和发送 开发环境:xp QT5.1.1 串口:38400 N 8 1 自动检测可用串口 在xp上测试没问题 有些usb转串口会出现波特 ...
- ROR 环境的 搭建
1)安装RUBY:从 http://www.ruby-lang.org/en/ 下载 ruby182-15.exe,安装Ruby.ruby -v 看是否安装成功.2)安装RAILS框架 :gem in ...
- C++第11周(春)项目2 - 职员有薪水了
课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 [项目2 - 职员有薪水了]定义一个名为CPe ...
- mysql-----gtid_executed详解 原创
MySQL 5.6版本开启GTID模式,必须打开参数log_slave_updates, 简单来说就是必须在从机上再记录一份二进制日志.这样的无论对性能还是存储的开销,无疑会相应的增大 而MySQL ...
- divide-conquer-combine(4.1 from the introduction to algorithm)
this example is from chapter 4 in <the introduction to algorithm> the main idea is all showed ...
- Gradle Goodness: Set Java Compiler Encoding--转载
原文地址:http://java.dzone.com/articles/gradle-goodness-set-java If we want to set an explicit encoding ...
- PHP.11-PHP实例(二)-面向对象实例(图形计算器)
面向对象实例(图形计算器) [PHP语法详解] 1.实现外观 #不同的动作,输出不同的表单 ###关于PHP中,无法使用localhost访问.php文件[http://www.360doc.com/ ...
- org.apache.hadoop.filecache-*
我不知道为什么这个包为什么是空的,从名字上看应该是一些管理文件缓存的类吗? 网上也没查到什么,各种群里也没大牛回答. 期望某位大牛能告诉我答案,谢谢
- Asp.Net 之 WebService部署到服务器后出现" The test form is only available for requests from the local machine "
最近由于任务需要开发了一个WebService, 部署到服务器以后,出现上述问题,网上查找到如下解决方案: 问题原因: 从 NET Framework 1.1 起定义了一个名为 HttpPostLoc ...
- const ;static;extern的使用与作用
const /** const :常量 const ...