您的位置:首页 > 编程语言 > Lua

Lua学习笔记(2) : 取得Lua中的变量

2015-11-30 23:48 260 查看

1. 引言

在第一个教程中介绍了于C++中运行Lua脚本的方法,在第二课就来介绍如何实现C++与Lua交互。

这一课的主题是要在C++程序中取得Lua脚本内的变量,我们先给出代码再进一步说明:

C++代码:

#include "include\lua.h"
#include "include\lauxlib.h"
#include "include\lualib.h"
#include "windows.h"

void main(int argc, char* argv[])
{
int var=0;

lua_State *pLua = luaL_newstate(); // Lua5.2后的版本遗弃lua_open(),改用luaL_newstate()
if(!pLua)
{
printf("Failed to open Lua.\n");
return;
}

luaL_openlibs(pLua); // Lua5.1以上使用此函数开启库

if(luaL_dofile(pLua, "luaDemo.lua")!=0) // 运行Lua腳本,若返回0则成功
{
printf("Failed to run lua.\n");
return;
}

lua_settop(pLua, 0); // Lua堆栈栈顶索引重置为0
lua_getglobal(pLua, "var"); // 取得Lua脚本中的var变量。
// 此时C++程序会把var字串推入堆栈,然后Lua把var从堆栈中取出,接着在全局表中查找出对应的值,然后把值推入堆栈。

if(lua_isnumber(pLua, -1)!=0) // 判断堆栈顶的值是否为我们要的数字型态的值,若返回非0则正確
{
var = lua_tonumber(pLua, -1); // 取出堆栈栈顶的值
}

printf("%d\n", var);

lua_close(pLua);

system("pause");
return;
}


Lua脚本:

var=5566


2. 载入脚本

代码延续前一篇的架构,不过载入脚本的方法我们稍作修改如下:

luaL_dofile(pLua, "luaDemo.lua");

在程序第20行,使用这个宏来读取Lua脚本并运行;

前一篇中是使用lua_dostring(L, buf);
将字串内容作为Lua脚本运行。

3. CPP与Lua交互

接下来要说明代码的主要部份,量不多,但重在理解,在這之前我们需要理解清楚C++与Lua是如何沟通的,才能搞清楚代码原理。

为了使Lua能和C++交互,Lua必须维护一个Lua堆栈,以及一个Lua全局表(global table);

Lua全局表是一张键值对(key-value)的表,储存Lua脚本中的所有全局变量,每个lua_State结构体都会拥有一个全局表来维护Lua脚本中的全局变量。

Lua堆栈则是C++与Lua沟通的中间人,因为他们不能理解彼此的语言,因此需要藉由一个管道来互相沟通,

当C++想获取Lua中全局变量的值时,需要接着进行以下步骤:

(1) C++把想获取的变量值之变量名以字符串推入堆栈

(2) Lua将该变量名字符串从堆栈中取出

(3) Lua到全局表中查找与变量名相同的键,以及该键对应的值,并且将值返回Lua

(4) Lua把该值推入堆栈

(5) C++就可以从堆栈顶端取得变量对应的

除了可以获得变量之值以外,C++想调用Lua脚本中的函数得到返回结果时也是透过堆栈沟通。

4. 取得Lua脚本中的变量

通过上方的描述,各位应该稍微理解C++取得Lua变量的方式了,若还有些模糊,我们一起从代码实例理解。

在25行我们首先重置C++与Lua互相沟通所使用到的Lua堆栈索引,呼叫lua_settop函数将堆栈栈顶索引设置为0,0作为第二个参数传入函數;

接着就可以开始取得变量值了,

26行呼叫lua_getglobal函数,将变量名字符串"var"作为第二个参数传入函数,此时变量名var就会推入堆栈,然后Lua就会取出变量名var,找出对应的值,再将值推回堆栈。

OK~ 至此,任务已经完成一半了,最后就是要让C++取得堆栈的内容。

在C++中可以呼叫lua_tonumber这个宏来取得堆栈中的值,取值的索引则是-1,作为第二个参数传入;

顺带一提,在Lua堆栈中用负数表达索引值是由堆栈顶端往下以-1, -2, -3, -4, ...........依序递减;若用正数表达则是由堆栈底端往上以1, 2, 3, 4, .........依序递增;

在本篇的情境下,由于我们的堆栈中只存有一个变量值,因此欲取得此值时可以-1或1指定索引,

如此一来就可以通过函数返回值取得变量值了。

另外,为了增强取值时的安全性,我们可以添加额外的验证,

在29行使用了lua_isnumber这个函数检查我们要取得的变量值是否为我们想要的型态,若函数返回值不为0则验证通过,可继续从堆栈中取得变量值。

5. Output

以上就是程序的主要运行过程说明,在运行完整代码的情况下,程序将会输出 5566

谢谢收看,下集待续。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: