lua与C的交互中,经常会遇到upvalues,那么什么是upvalue呢?
简单的说,upvalue就是lua函数中引用到的外部变量.这么说有两层意思:
1 他不是函数的局部变量,即在函数中没有用local修饰
2 他不是全局变量,即他在函数外部还是要用local修饰
local upval = 123
local fun()
upval = upval + 1 --upval就是函数fun的upvalue
local var = 456 --不是upvalue
global_val = 789 --也不是upvalue
end
在与C的交互中,可以用lua_getupvalue来获取upvalue的名字,并把它的值压栈,例如:
lua_getglobal(L, "fun"); //获取全局变量'fun',并压栈
const char *name = lua_getupvalue(L, -1, 1); //返回栈-1上第1个upvalue的名字,并把它压栈,现在栈顶是123
对应的
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
则是把stack[funindex]函数的第n个upvalue设置为栈顶的值,并pop栈顶,返回他的变量名
注意,如果函数没有外部局部变量,有全局变量,那么lua_getupvalue返回的是全局table:_ENV,然后通过操作表,也可以改变这个全局变量.
在C语言向lua注册函数的的时候,也可以设置upvalue
void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n)
压入一个函数到栈顶.
比如我要在lua中执行一个c函数,可以用lua_pushcclosure压入c本地函数到栈顶,然后给该函数命名为lua中要执行的函数名(调用lua_setglobal(L, "funName")),这样lua代码就能执行c的函数了.其实有这个过程的宏定义了:lua_register(L, f, funName)
我们注意到lua_pushcclosure函数还有一个参数n,他的含义是upvalue的个数.upvalue简单的理解就是要给这个函数设置这个函数作用域可见的变量.
比如,我在给栈顶压入一个函数时,先压入一个upvalue,这样在函数调用中就能取到那个upvalue了:
- lua_pushinteger(L, 100); --压入一个upvalue 100
- lua_pushcclosure(L, myAdd, 1); --压入函数,并带一个upvalue值,从栈顶取,即上面的100
- lua_setglobal(L, "myAdd");
- lua代码 myAdd(3,5)
- static int myAdd(lua_State* L)
- {
- int k = lua_tonumber(L, lua_upvalueindex(1)); --对应upvalue 100
- int n = lua_gettop(L);
- double op1 = luaL_checknumber(L, 1);
- double op2 = luaL_checknumber(L, 2);
- lua_pushnumber(L, op1 - op2);
- n = lua_gettop(L);
- return 2;
- }