lua c closure的使用

来源:互联网 发布:centos 7安装snmp服务 编辑:程序博客网 时间:2024/06/01 07:13

closure,闭包,即值和函数的绑定,本身也可作为函数调用,用于绑定的函数也可以称为函数模板。

闭包的关键在于绑定 值与函数,以及如何在函数中定位到这些绑定的值,这些值又叫upvalue。

每一个lua closure都有一个独立的闭包环境,宏 lua_upvalueindex(index) 可以获得第index个值的索引,藉由这些索引,可以对闭包内的upvalue读写。

1,创建闭包

关键函数是int lua_pushcclosure(lua_State *L,lua_CFunction func,int n ),其中n是堆栈顶端值得个数,这些值将复制到closure中,func是使用closure的函数,这个函数调用后会清除栈中n个值,会压入一个closure到栈中。

2,访问upvalue

当一个closure被调用,这个closure指定的函数就能通过upvalueindex索引访问所有upvalue。

比如:

int num=lua_tointeger(L,lua_upvalueindex(1));//获得第一个upvalue的值int table_len=lua_objlen(L,upvalueindex(2));//获得第二个upvalue的长度puts(lua_tostring(L,lua_upvalueindex(3)));//输出第三个upvalue

需要注意的是,upvalue的索引是和这些值压入顺序一致的。

修改一个upvalue:

lua_pushstring(L,"Hello");lua_replace(L,lua_upvalueindex(1));//修改upvalue可以使用lua_replace函数,使用栈顶的值替换具体索引的值
3,代码例子

#include <lua.h>#include <lualib.h>#include <lauxlib.h>
#pragma comment(lib,"lua5.1.lib")#pragma comment(lib,"lua51.lib")
<span style="font-family: Arial, Helvetica, sans-serif;">/*</span>
<span style="white-space:pre"></span>文件名 3.c
<span style="white-space:pre"></span>模块名 3
<span style="white-space:pre"></span>Windows:3.dll
*/#define l_typename(L,index) lua_typename(L,lua_type(L,index))static int index_plus(lua_State *L){//正常的迭代器函数int table_len=lua_objlen(L,lua_upvalueindex(1));int index=lua_tointeger(L,lua_upvalueindex(2));if(index>table_len){lua_pushnil(L);return 1;}lua_pushinteger(L,index+1);lua_pushvalue(L,-1);lua_replace(L,lua_upvalueindex(2));lua_rawget(L,lua_upvalueindex(1));return 1;}static int index_null(lua_State *L){//空的迭代器函数lua_pushnil(L);return 1;//return nil}static int make_index(lua_State *L){//生成迭代器int top=lua_gettop(L);int index;if(LUA_TTABLE!=lua_type(L,1)){//第一个类型不是表lua_pushcclosure(L,index_null,0);return 1;}lua_pushvalue(L,1);lua_pushinteger(L,lua_tointeger(L,2));lua_pushcclosure(L,index_plus,2);return 1;}int luaopen_3(lua_State *L){//引用这个库所调用的函数lua_newtable(L);lua_pushstring(L,"make_index");lua_pushcfunction(L,make_index);lua_rawset(L,-3);return 1;}

编译命令:

cl /LD 3.c out.def
其中out.def文件:

LIBRARY 3;EXPORTSluaopen_3 @1;

运行这个库的lua脚本:

local t=require '3'for value in t.make_index{3,2,"这是","第一","次","发帖"} doprint(tostring(value))end

运行结果

0 0
原创粉丝点击