我正在尝试Lua,想知道lua_State是如何工作的 代码和结果:
state.c
#include <stdio.h>
#include "lua/src/lua.h"
#include "lua/src/lauxlib.h"
static void stackDump(lua_State *L){
int i;
int top = lua_gettop(L);
for(i = 1; i<= top; i++) {
int t = lua_type(L, i);
switch(t){
case LUA_TSTRING:
printf("'%s'", lua_tostring(L, i));
break;
case LUA_TBOOLEAN:
printf(lua_toboolean(L, i) ?"true":"false");
break;
case LUA_TNUMBER:
printf("%g", lua_tonumber(L, i));
break;
default:
printf("%s", lua_typename(L, t));
break;
}
printf(" ");
}
printf("\n");
}
static int divide(struct lua_State *L){
double a = lua_tonumber(L, 1);
double b = lua_tonumber(L, 2);
printf("%p\n", L);
stackDump(L);
int quot = (int)a / (int)b;
int rem = (int)a % (int)b;
lua_pushnumber(L, quot);
lua_pushnumber(L, rem);
stackDump(L);
printf("---end div---\n");
return 2;
}
int main(void){
struct lua_State *L = lua_open();
lua_pushboolean(L, 1);
lua_pushnumber(L, 10);
lua_pushnil(L);
lua_pushstring(L, "hello");
printf("%p\n", L);
stackDump(L);
lua_register(L, "div", divide);
luaL_dofile(L, "div.lua");
stackDump(L);
lua_close(L);
return 0;
}
div.lua
local c = div(20, 10)
0x100c009e0
真正的10无'你好' ---开始div ---
0x100c009e0
20 10
20 10 2 0
---结束div ---
真正的10无'你好'
我看到lua_State
中的divide
与main
的{{1}}相同,但它们在堆栈中有不同的数据,如何做?
我知道理解这个的最好方法是阅读Lua的源代码,也许你可以告诉我在哪里找到合适的地方。
答案 0 :(得分:3)
将lua_State视为包含Lua堆栈,以及分隔堆栈当前可见部分的索引。当你调用Lua函数时,它可能看起来像你有一个新的堆栈,但实际上只有索引已经改变。那是简化版。
lua_State
在lstate.h
中定义。我已经为你拉出了相关的部分。 stack
是包含所有内容的大型Lua堆栈的开头。 base
是当前函数的堆栈的开头。这是你的函数在执行时看作“堆栈”的东西。
struct lua_State {
/* ... */
StkId top; /* first free slot in the stack */
StkId base; /* base of current function */
/* ... */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
/* ... */
};
Lua编程,第2版在第30章讨论Lua状态:线程和状态。你会在那里找到一些好消息。例如,lua_State
不仅表示Lua状态,还表示该状态内的线程。此外,所有线程都有自己的堆栈。
答案 1 :(得分:2)
它以不同的方式获取不同的数据任何获取不同的数据:代码更改对象内部的数据。
struct Object
{
int val;
};
void more_stuff(Object *the_data)
{
//the_data->val has 5 in it now.
}
void do_stuff(Object *the_data)
{
int old_val = the_data->val;
the_data->val = 5;
more_stuff(the_data);
the_data->val = old_val;
}
int main()
{
Object my_data;
my_data.val = 1;
//my_data.val has 1.
do_stuff(&my_data);
//my_data.val still has 1.
}
答案 2 :(得分:0)
当Lua调用已注册的C函数时,它会为它提供一个新的堆栈帧。