lua c closure的使用
2016-01-14 19:16
531 查看
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。
比如:
需要注意的是,upvalue的索引是和这些值压入顺序一致的。
修改一个upvalue:
编译命令:
运行这个库的lua脚本:
闭包的关键在于绑定 值与函数,以及如何在函数中定位到这些绑定的值,这些值又叫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; EXPORTS luaopen_3 @1;
运行这个库的lua脚本:
local t=require '3' for value in t.make_index{3,2,"这是","第一","次","发帖"} do print(tostring(value)) end
相关文章推荐
- lua 绑定c++
- liunx 下 C/C++调用luajit
- 用lua写Android界面学习笔记
- [转载]轻量级Lua IDE ZeroBrane Studio 的使用技巧和汉化
- 从零开始——Windows环境lua编程
- leetcode--Evaluate Reverse Polish Notation
- Lua 表达式
- Lua中and、or的一些特殊用法
- Lua 类型和值
- 【sublime】编译lua
- wax lua 简介
- Lua - coroutine 状态与数据交换
- 快速掌握Lua 5.3 —— 各种运算符以及各种声明
- Lua Module
- Lua 5.1 参考手册
- lua的string库
- 快速掌握Lua 5.3 —— 让我们开始吧
- openresty lua学习笔记
- Lua 独立解释器
- Lua 全局变量