常用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博客

Lua 5.1 Reference Manual

 

posted @ 2025-02-17 23:38  yanghui01  阅读(139)  评论(0)    收藏  举报