1.简介
这一节介绍一些关于栈操作、数据类型判断的LUA API,可以使用这些函数获得脚本中的变量值。2.步骤
- 编写 test01.lua 脚本
- 在VS2003中创建控制台C++程序并正确配置
- 执行查看结果,修改test02.lua脚本后查看执行结果
3.测试脚本
以下是用来测试的lua脚本function plustwo(x)
local a;
a = 2 ;
return x + a;
end ;
rows = 6 ;
cols = plustwo(rows);
上面的脚本定义了一个函数、两个全局变量(LUA脚本变量默认是全局的)。
之后的C++程序中,我们将通过栈操作获得这两个变量 rows, cols
4.控制台程序





















































































5.程序解释
5.1 申请一个LUA虚拟机
LUA脚本的编译执行是相互独立的,在不同的线程上执行。通过lua_open()函数可以申请一个虚拟机,返回指针类型 lua_State。今后其他所有LUA Api函数的调用都需要此指针作为第一参数,用来指定某个虚拟机。5.2 异常信息
程序中的iError变量获取每个LUA API的执行结果,如果结果非零则说明出现异常,因此可以看到示例代码中,每次调用一个API函数都会对结果进行判断,如果发现异常则输出提示、关闭虚拟机、结束程序。5.3 程序过程
luaL_loadfile() 动态载入一段脚本文件lua_pcall() 执行脚本
lua_getglobal(STATE "VAR") 将LUA脚本中名字为VAR的全局变量压入堆栈
lua_isnumber() 数据类型判断
lua_tonumber() 返回栈中的某个值
lua_pop() 出栈请求
lua_close() 关闭lua虚拟机
6. LUA和C++的沟通桥梁——栈
程序中反复使用到的栈是LUA和C++程序的数据中转站。LUA API对栈进行了一些定义:6.1 传统栈操作被支持
对栈的数据的出入操作和传统的栈相同,使用POP/PUSH。例如示例程序中的
- lua_pop(L,2)请求L虚拟机出栈两个成员。
- lua_getglobal()将指定的变量压栈。
6.2 栈成员访问支持索引
为了方便起见,大多数查询操作的API不需要遵守FILO。他们可以使用 索引(index)引用任何栈中元素:一个正数索引代表了栈中的绝对位置(从1开始);一个负数索引代表了从栈顶的偏移量。更特别的是,如果栈有 n 个元素,那么索引 1 代表第一个元素(这就是说,这个元素首先入栈)并且索引 n 代表了最后一个元素;索引 -1 也代表了最后一个元素(也就是栈顶)并且索引 -n 代表了第一个元素。我们说一个索引存在于 1 和栈顶之间是有效的,换句话说,如果 1 <= abs(index) <= top。以下是LUA API提供的栈操作函数:
void lua_settop (lua_State * L, int index);
void lua_pushvalue (lua_State * L, int index);
void lua_remove (lua_State * L, int index);
void lua_insert (lua_State * L, int index);
void lua_replace (lua_State * L, int index);
下面几个例子可以说明他们的用途:
如果栈开始于 10 20 30 40 50*(自底向上;`*´ 标记了栈顶),那么:
lua_pushvalue(L, 3) --> 10 20 30 40 50 30*
lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30*
lua_remove(L, -3) --> 10 20 30 40 30 30*
lua_remove(L, 6) --> 10 20 30 40 30*
lua_insert(L, 1) --> 30 10 20 30 40*
lua_insert(L, -1) --> 30 10 20 30 40* (no effect)
lua_replace(L, 2) --> 30 40 20 30*
lua_settop(L, -3) --> 30 40*
lua_settop(L, 6) --> 30 40 nil nil nil nil*
6.3 栈查询
在取值之前可能需要对成员类型进行验证,下面的函数可以用来检测栈内元素的类型:int lua_type (lua_State * L, int index);
int lua_isnil (lua_State * L, int index);
int lua_isboolean (lua_State * L, int index);
int lua_isnumber (lua_State * L, int index);
int lua_isstring (lua_State * L, int index);
int lua_istable (lua_State * L, int index);
int lua_isfunction (lua_State * L, int index);
int lua_iscfunction (lua_State * L, int index);
int lua_isuserdata (lua_State * L, int index);
int lua_islightuserdata (lua_State * L, int index);
这些函数只能使用可接受的索引。
lua_type 返回栈中元素值的类型,如果所有索引无效则返回 LUA_TNONE(就是说如果栈为空)。这些lua_type 代表的返回值作为常量定义在 lua.h 中:LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, LUA_TLIGHTUSERDATA。下面的函数将这些常量转换成字符串:
const char * lua_typename (lua_State * L, int type);
lua_is* 函数返回 1 当对象与所给类型兼容的时候,其他情况返回 0。 lua_isboolean 是一个例外:它只针对布尔值时才会成功(否则将是无用的,因为任何值都是一个布尔值)。这些函数对于无效引用返回 0。 lua_isnumber 接受数字和用数字表示的字符串;lua_isstring 接受字符串和数字(见 2.2.1);lua_isfunction 接受Lua函数和C函数; lua_isuserdata 接受完整的和轻量的用户数据。要区分C 函数和Lua 函数,你可以使用 lua_iscfunction。要区分用户数据,你可以使用 lua_islightuserdata。要区分数字还是用数字表示的字符串,你可以使用 lua_type。
6.4 从栈中取值
为了将一个栈中的值转变为指定的C语言类型,你需要使用以下的转换函数:









6.5 向栈压值
我们可以从栈中获取来自LUA脚本的变量值,同样可以可以将C++程序中的数据放入栈中。void lua_pushboolean (lua_State * L, int b);
void lua_pushnumber (lua_State * L, lua_Number n);
void lua_pushlstring (lua_State * L, const char * s, size_t len);
void lua_pushstring (lua_State * L, const char * s);
void lua_pushnil (lua_State * L);
void lua_pushcfunction (lua_State * L, lua_CFunction f);
void lua_pushlightuserdata (lua_State * L, void * p);