通过上一篇的热身,我们对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交互(三)的更多相关文章

  1. C++与Lua交互之配置&交互原理&示例

    |Lua 简介 Lua 是一种轻量小巧的脚本语言,也是号称性能最高的脚本语言,它用C语言编写并以源代码形式开放. 某些程序常常需要修改内容,而修改的内容不仅仅是数据,更要修改很多函数的行为. 而修改函 ...

  2. C++与Lua交互(四)

    引言 通过前几篇,我们已经对Lua的C API有了一定的了解,如lua_push*.lua_is*.lua_to*等等.用C++调用Lua数据时,我们主要运用lua_getglobal与lua_pus ...

  3. C++与Lua交互(一)

    引言 之前做手游项目时,客户端用lua做脚本,基本所有游戏逻辑都用它完成,玩起来有点不爽,感觉"太重"了.而我又比较偏服务端这边(仅有C++),所以热情不高.最近,加入了一个端游项 ...

  4. lua视频教程三套高清新

    目录 1. 下载地址 2. 某网校 Lua 经典教程 3. lua脚本语言零基础开发教程19课全 4. LUA完整视频+Cocos2d-x项目实战 1. 下载地址 https://www.cnblog ...

  5. Win32下 Qt与Lua交互使用(三):在Lua脚本中connect Qt 对象

    话接上文.笔者为了方便使用Lua,自己编写了一个Lua的类.主要代码如下: QLua.h #ifndef QLUA_H #define QLUA_H // own #include "inc ...

  6. C++与Lua交互(二)

    上一篇我们搭建好了整个的项目环境,现在,我们一起探索一下如何将lua寄宿到C++中. 宿主的实现 我们在LuaWithCPPTest项目下,查看Source.cpp代码如下: #include < ...

  7. 最优雅的C++跟lua交互.

    我先来吐槽一下我们这个项目. 我是做手机游戏的, cocos2dx引擎, lua编码. 这本来是一件很欢快的事情, 因为不用接触C++. C++写久了的人写lua, 就会感觉任督二脉被打通了, 代码写 ...

  8. C++与lua交互

    项目开发的脚本层用的是Lua,引擎用的是C++.但是经理不给开放引擎层的代码.刚好最近项目空闲,安排了学习C++跟Lua的通信. 一.C++与Lua数据交互 数据交互主要是通过C API来实现 首先, ...

  9. 整理Lua和Unity和Lua交互文章链接

    重点文章: 1.[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 2.[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(中) 3.Lua和C++交互详细总结 4. ...

随机推荐

  1. android拦截短信并屏蔽系统的Notification

    拦截短信有几个关键点: 1.android接收短信时是以广播的方式 2.程序只要在自己的Manifest.xml里加有"接收"SMS的权限 <uses-permission  ...

  2. AttributeBehavior

    当事件触发的时候... 会循环所有behavior的events  为ower添加事件.....AttributeBehavior  为事件添加如下方法 public function evaluat ...

  3. MapReduce原理讲解

    简介 本文主要介绍MapReduce V2的基本原理, 也是笔者在学习MR的学习笔记整理. 本文首先大概介绍下MRV2的客户端跟服务器交互的两个协议, 然后着重介绍MRV2的核心模块MRAppMast ...

  4. Java元组类型之javatuples

    转载:Java元组类型之javatuples 关于方法的返回值,经常需要返回2个值或多个值的一个序列,比如数据表的一条记录,文件的一行内容等.除了使用数组Array.集合(List.Set.Map)这 ...

  5. Ruby on Rails Tutorial 第二章 之 微博资源

    1.微博模型如下图所示: 2.创建微博资源,命令如下: $ rails generate scaffold Micropost content:text user_id:integer  #生成微博资 ...

  6. linux后端运行

    程序命令 & :将命令放入后台运行. Ctrl + z : 把一个正在运行的前端命令转移到后台运行,它等效于:程序命令 & :这样虽然把程序放在了后端运行,但是此时程序状态为暂停状态, ...

  7. jQuery获取表单各元素的值

    radio值获取 $("input[type='radio']:checked").val(); 2,设置指定的项为当前选中项 $("input[type='radio' ...

  8. Mac 下配置Tomcat7和eclipse中配置tomcat

    转载自: http://www.cnblogs.com/weilaikeji/archive/2013/05/29/3106473.html 1.下载Tomcat 从Tomcat项目主页下载相关压缩包 ...

  9. 用jQuery+easyUI遇到的几个插件与文件详解

    很早就开始跟着老师学习jQuery课程,那时候是要求熟练使用jQuery中的easyUI插件中的控件,包括textbox.combobox.panel.checkbox.tree.datagrid等等 ...

  10. [课程相关]homework-08

    一.变量作用域和生命周期 #include <cstdlib> #include <iostream> using namespace std; void try_change ...