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. ...
随机推荐
- 【经验记录】Android上传文件到服务器
Android中实现上传文件,其实是很简单的,和在java里面是一样的,基本上都是熟悉操作输出流和输入流!还有一个特别重要的就是需要配置content-type的一些参数!如果这些都弄好了,上传就很简 ...
- 发布站点到远程FTP根目录
第一步:修改 phpcms/modules/admin/templates/site_add.tpl.php 找到 <legend><?php echo L('release_poi ...
- 基于Linux的owncloud搭建
为了保证一个纯净的环境,我重新安装了一台centos系统 [root@localhost httpd-2.2.23]# lsb_release -a LSB Version: :base-4.0 ...
- swift3.0 中NSNotification 的使用
swift3.0 有很大变化,其中之一就是NSNotification使用跟原来不一样,以前NSNotification name是String:3.0中定义了一个类型NSNotification.n ...
- UNIX基础知识之信号
本篇博文内容摘自<UNIX环境高级编程>(第二版),仅作个人学习记录所用.关于本书可参考:http://www.apuebook.com/. 信号(signal)是通知进程已发生某种情况的 ...
- Windows 之 获取管理员权限
新建文本文档,写入如下内容: Windows Registry Editor Version 5.00 [-HKEY_CLASSES_ROOT\*\shell\runas] [HKEY_CLASSES ...
- MeasureSpec介绍
在自定义View和ViewGroup的时候,我们经常会遇到int型的MeasureSpec来表示一个组件的大小,这个变量里面不仅有组件的尺寸大小,还有大小的模式. 这个大小的模式,有点难以理解.在系统 ...
- hdu 3440 差分约束
看完题目第一遍,感觉很简单.当写完程序跑测试用例的时候,发现第二个总是过不了,然后好好研究了一下测试用例,才知道原来不是程序有问题,而是我的建图方式错了.对于这些无序的点,如果高的在右边,不等式是di ...
- hishop网站迁移后出现DataProtectionConfigurationProvider错误(转)
配置错误说明: 在处理向该请求提供服务所需的配置文件时出错.请检查下面的特定错误详细信息并适当地修改配置文件.分析器错误信息: 未能使用提供程序“DataProtectionConfiguration ...
- C#算法基础之快速排序
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...