常用lua c api
lua栈索引顺序说明
从栈顶往栈底:-1, -2, -3......
从栈底往栈顶: 1, 2, 3......
操作表
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); //创建新表, 压入栈顶, narr为初始数组大小, nrec为初始hash表大小 #define lua_newtable(L) lua_createtable(L, 0, 0) LUA_API int (lua_setmetatable) (lua_State *L, int objindex); //操作对象为栈[objindex]处的值, metatable为栈顶的值。栈顶弹出1个元素 LUA_API void (lua_rawset) (lua_State *L, int idx); //操作对象为栈[idx]处的值, key为栈[-2]的值, value为栈顶的值。栈顶弹出2个元素 LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); //操作对象为栈[idx]处的值, key为栈[n]的值, value为栈顶的值。栈顶弹出1个元素 LUA_API void (lua_rawget) (lua_State *L, int idx); //操作对象为栈[idx]处的值, key为栈顶的值, 弹出栈顶元素, obj[key]压入栈顶 LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); //操作对象为栈[idx]处的值, key为栈[n]的值, obj[key]压入栈顶, 不会弹出栈元素 LUA_API void (lua_settable) (lua_State *L, int idx); //操作对象为栈[idx]处的值, key为栈[-2]的值, value为栈顶的值。栈顶弹出2个元素 LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); //操作对象为栈[idx]处的值, key由参数k提供, value为栈顶的值。栈顶弹出1个元素 #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) //操作对象为全局表, key由参数提供, value为栈顶的值。栈顶弹出1个元素 LUA_API void (lua_gettable) (lua_State *L, int idx); //操作对象为栈[idx]处的值, key为栈顶的值,弹出栈顶元素,obj[key]压入栈顶 LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); //操作对象为栈[idx]处的值, key由参数k提供,obj[key]压入栈顶 #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) //操作对象为全局表, key由参数提供,obj[key]压入栈顶
栈元素转换
这部分api都不会操作栈
LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); //将栈[idx]处的值转换为浮点数; 出错时不会抛异常, 返回默认值 LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); //将栈[idx]处的值转换为浮点数, 出错时isnum会被设为0, lua5.2版本之后才有 LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); LUA_API int (lua_toboolean) (lua_State *L, int idx); LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); //将栈[idx]处的值转换为字符串, 并将字符串长度填充到len上(如果len不为NULL) #define lua_tostring(L, i) lua_tolstring(L, (i), NULL) //将栈[i]处的值转换为字符串 //栈[idx]处元素的长度,元素类型:1、字符串:字符串长度;2、table:#table长度;3、userdata:占用的字节数;4、其他类型:0 LUA_API size_t (lua_objlen) (lua_State *L, int idx); #define lua_strlen(L,i) lua_objlen(L, (i)) //栈[i]处元素为字符串时,可以用该宏来获取字符串长度 LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); LUA_API void*(lua_touserdata) (lua_State *L, int idx); LUA_API lua_State*(lua_tothread) (lua_State *L, int idx); LUA_API const void *(lua_topointer) (lua_State *L, int idx);
栈元素类型检查
这部分api不错操作栈
LUA_API int (lua_isnumber) (lua_State *L, int idx); //栈[idx]处的值是否为数字 LUA_API int (lua_isstring) (lua_State *L, int idx); //栈[idx]处的值是否为字符串 LUA_API int (lua_iscfunction) (lua_State *L, int idx); LUA_API int (lua_isuserdata) (lua_State *L, int idx); LUALIB_API const char *(luaL_checklstring) (lua_State *L, int narg, size_t *l); //检查栈[narg]处的元素类型是否为string, 返回该字符串, 并将字符串长度填充到l上;否则报异常。 #define luaL_checkstring(L, n) (luaL_checklstring(L, (n), NULL)) LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, const char *def, size_t *l); LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); //检查栈[numArg]处的元素类型是否为number, 返回该number; 否则报异常 LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); //检查栈[nArg]处的元素类型是否为number, 返回该number; 否则返回默认值 LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); //检查栈[numArg]处的元素类型是否为int, 返回该int; 否则报异常 LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, lua_Integer def); //检查栈[nArg]处的元素类型是否为int类型, 返回该int; 否则返回默认值 LUA_API int (lua_type)(lua_State *L, int idx); //栈[idx]处的元素类型 LUA_API const char*(lua_typename) (lua_State *L, int tp); //类型名字, tp为lua_type函数返回的类型值 #define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) #define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) #define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) #define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) #define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
栈顶push元素
LUA_API void (lua_pushnil) (lua_State *L); //nil压入栈顶 LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); //浮点数压入栈顶 LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); //整数压入栈顶 LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); //压入指定长度的字符串 LUA_API void (lua_pushstring) (lua_State *L, const char *s); //压入字符串, 长度由\0决定 LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, va_list argp); LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); LUA_API void (lua_pushboolean) (lua_State *L, int b); //boolean压入栈顶 LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); //将指针变量的值(地址值)压入栈顶 LUA_API int (lua_pushthread) (lua_State *L); //线程状态压入栈顶 #define lua_pushliteral(L, s) lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) //压入常量字符串 LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) //没有upvalue的pushcclosure
栈操作
LUA_API int (lua_gettop) (lua_State *L); //获取栈元素数量 LUA_API void (lua_settop) (lua_State *L, int idx); //设置栈元素数量, idx更大用nil补足, idx更小清掉多余元素 void lua_pop (lua_State *L, int n); //栈顶弹出n个元素 LUA_API void (lua_pushvalue) (lua_State *L, int idx); //栈[idx]处的元素再压到栈顶 LUA_API void (lua_remove) (lua_State *L, int idx); //移除栈idx处的元素 LUA_API void (lua_insert) (lua_State *L, int idx); //将栈顶元素移到栈idx处 LUA_API void (lua_replace) (lua_State *L, int idx); //弹出栈顶元素, 并将栈[idx]处替换为该元素 void lua_xmove (lua_State *a, lua_State *b, int n); //从栈a弹出n个元素, 压入栈b
全局注册表
该表对应的索引为LUA_REGISTRYINDEX,使用lua_pushvalue(L, LUA_REGISTRYINDEX)压入栈顶
int (luaL_newmetatable) (lua_State *L, const char *tname); // 创建一个新表(后续作为元表)压入栈顶, 并将该表存入全局注册表的tname处。 #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) // 从全局注册表获取名字为n的表(后续作为元表), 并压入栈顶, 如果没有则压入nil LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); // 检查栈[ud]处的用户数据的元表, 是否为全局注册表[tname]的值, 返回该用户数据或NULL
c代码中执行lua
LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); #define luaL_dofile(L, fn) (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name); LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); #define luaL_dostring(L, s) (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, const char *chunkname);
其他
引用持有或释放
LUALIB_API int (luaL_ref) (lua_State *L, int t); //弹出栈顶元素, 为它分配一个唯一id, 并将它存在栈[t][id]处, 返回该id LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); //栈[t][ref] = nil, 这样对应的对象可以被回收
LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); //调用函数
例如:lua_call(c->L, 2, 1); //栈[-3]为操作对象, 栈[-2]为第1个参数, 栈[-1]为第2个参数, 执行完栈顶弹出3个元素, 1个函数返回值压入栈顶
报异常
int luaL_argerror (lua_State *L, int narg, const char *extramsg); //报异常(格式类似:bad argument #2 to 'Xxx函数' (param type not string)),且不再往下执行。 int lua_error (lua_State *L); //报异常, 使用栈顶文本作为错误描述, 不会再往下执行。
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); //新建一个lua虚拟机实例 LUALIB_API lua_State *(luaL_newstate) (void); //新建一个lua虚拟机实例 #define lua_open() luaL_newstate() //新建一个lua虚拟机实例, lua5.1之后请用luaL_newstate() LUA_API void (lua_close) (lua_State *L); //销毁lua虚拟机实例
参考
C++ 与 Lua 数据交互载体——栈_Lua-CSDN专栏
Lua5.1编程四:Lua与C交互基础_lua5.1 注册函数的方法-CSDN博客

浙公网安备 33010602011771号