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

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

谢谢收看,下集待续。


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值