Lua常用c函数分析

本文详细分析了Lua中与C语言交互的关键C函数,包括创建表、获取和设置表元素、创建和操作用户数据以及注册C函数等,旨在帮助读者更好地理解和使用Lua的C API。
摘要由CSDN通过智能技术生成

虽然有lua参考手册,但是为了更加清晰,自己再总结一下


typedef struct lua_State lua_State
/* 一个不透明的结构,它保存了整个 Lua 解释器的状态
Lua 库是完全可重入的:它没有任何全局变量。
(译注:从 C 语法上来说,也不尽然。例如,在 table 的实现中用了一个静态全局变量 dummynode_ ,
但这在正确使用时并不影响可重入性。只是万一你错误链接了 lua 库,
不小心在同一进程空间中存在两份 lua 库实现的代码的话,多份 dummynode_ 不同的地址会导致一些问题。)
所有的信息都保存在这个结构中。这个状态机的指针必须作为第一个参数传递给每一个库函数。 
lua_newstate 是一个例外,这个函数会从头创建一个 Lua 状态机
*/
----------------------------------------------------------------------------------


void lua_createtable (lua_State *L, int narr, int nrec){}
/* 建一个新表
创建一个新的table, 并把它放在栈顶. narr和nrec分别指定该table的array部分和hash部分的预分配元素数量 
无返回值  栈高度+1, 
栈顶元素是新table  
#define lua_newtable(L) lua_createtable(L, 0, 0) 常用这个
*/
----------------------------------------------------------------------------------


void lua_getfield (lua_State *L, int index, const char *k){}
/* 取表中的元素
操作:   arr = Stack[index]    // arr肯定是表 
Stack.push( arr[k] )  
取表中键为k的元素, 这里的表是由index指向的栈上的一个表 
无返回值  
栈高度+1, 栈顶元素是(Stack[index])[k] 
注意, 该操作将触发 __index 元方法
*/
----------------------------------------------------------------------------------


void lua_setfield (lua_State *L, int index, const char *k){}
/* 给表中的元素赋值
操作:   arr = Stack[index] 
arr[k] = Stack.top() 
Stack.pop()  
给表中键为k的元素赋值value(value就是栈顶元素), 这里的表是由index指向的栈上的一个表 
无返回值  
栈高度-1, 被弹出的是value  
注意, 该操作将触发 __newindex 元方法
*/
----------------------------------------------------------------------------------


void lua_gettable (lua_State *L, int index){}
/* 取表元素
操作: ele  = Stack[index] 
key = Stack.top() 
Stack.pop() 
value = ele[key] 
Stack.push(value)  
根据index指定取到相应的表; 取栈顶元素为key, 并弹出栈; 获取表中key的值压入栈顶. 
无返回值  栈高度不变, 但是发生了一次弹出和压入的操作, 弹出的是key, 压入的是value 
注意, 该操作将触发 __index 元方法
*/
----------------------------------------------------------------------------------


void lua_settable (lua_State *L, int index){}
/* 表元素赋值
操作:   ele    = Stack[index] 
value  = Stack.top() 
Stack.pop()  
key    = Stack.top() 
Stack.pop() 
ele[key] = value   
根据index指定取到相应的表; 取栈顶元素做value, 弹出之; 再取当前栈顶元素做key, 亦弹出之; 然后将表的键为key的元素赋值为value 
无返回值  
栈高度-2, 第一次弹出value, 第二次弹出key 
注意, 该操作将触发 __newindex 元方法
*/
----------------------------------------------------------------------------------


void lua_rawget (lua_State *L, int index){}
/* 取表元素
和lua_gettable操作一样 但是不触发相应的元方法
*/
----------------------------------------------------------------------------------


void lua_rawgeti(lua_State *L, int index, int n){}
/* 取表元素
操作:   ele = Stack[index] 
value = ele[n] 
Stack.push(value)   
无返回值  栈+1,栈顶新增元素就是 value 
不触发相应的元方法
*/
----------------------------------------------------------------------------------


void lua_rawset (lua_State *L, int index){}
/* 表元素赋值
和lua_settable操作一样 但是不触发相应的原方法
*/
----------------------------------------------------------------------------------


void lua_rawseti (lua_State *L, int index, int n){}
/* 表元素赋值
操作:   ele = Stack[index] 
value = Stack.top() 
Stack.pop() 
ele[n] = value 
无返回值  栈-1, 栈顶将value弹出 
不触发相应的元方法
*/
----------------------------------------------------------------------------------


void lua_pushvalue (lua_State *L, int index){}
/* 复制栈上元素并压入栈
操作:   value = Stack[index] 
Stack.push(value) 
无返回值 栈+1 
*/
----------------------------------------------------------------------------------


int luaL_newmetatable (lua_State *L, const char *tname){}
/* 创建一个元表 
操作:   
1. 在注册表中查找tname, 如果已经注册, 就返回0, 否者继续, 并平栈         
lua_getfield(L, LUA_REGISTRYINDEX, tname) 
if (!lua_isnil(L, -1)) 
return 0;          
lua_pop(L, 1);           
2. 创建一个表, 并注册, 返回1         
lua_newtable(L)         
lua_pushvalue(L, -1)          
lua_setfield(L, LUA_REGISTRYINDEX, tname) 
return 1 
有返回值  栈+1, 栈顶元素是在注册表中注册过的新表
*/
----------------------------------------------------------------------------------


void *lua_newuserdata (lua_State *L, size_t size){}
/* 创建C值
该函数分配一块由size指定大小的内存块, 并放在栈顶 
返回值是新分配的块的地址 
栈+1,栈顶是userdata  
userdata用来在lua中表示c中的值. 一个完整的userdata有自己的元表, 在垃圾回收时, 可以调用它的元表的__gc方法
*/
----------------------------------------------------------------------------------


void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n){}
/* 注册c函数到lua中, 其实没有这回事, lua中只有c闭包
向栈上压一个C闭包  
当一个c函数被创建时, 可以绑定几个值在它上面, 从而形成一个闭包.  在任何时刻调用这个c函数时, 都可以访问这几个绑定值.   
绑定的方法: 先一次压入要绑定的n个值到栈上, 然后调用lua_pushcclosure(L, fn, n)这样就形成的一个c闭包 
无返回值  栈–(n - 1) , 一共弹出n个元素(及那些绑定的值), 压入一个cclosure 


#define lua_pushcfunction(L, f) lua_pushcclosure(L, f, 0)  
#define lua_register(L, n, f) (lua_pushcfunction(L, f), lua_setglobal(L, n)) 
*/
----------------------------------------------------------------------------------


const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n){}
/* 设置给定活动记录中的局部变量的值。
参数 ar 与 n 和 lua_getlocal 中的一样(参见 lua_getlocal)。 
lua_setlocal 把栈顶的值赋给变量然后返回变量的名字。它会将值从栈顶弹出。
当索引大于局部变量的个数时,返回 NULL (什么也不弹出)


栈高 -1 或者不变
*/
----------------------------------------------------------------------------------


const char *lua_setupvalue (lua_State *L, int funcindex, int n){}
/* 设置 closure 的 upvalue 的值
它把栈顶的值弹出并赋于 upvalue 并返回 upvalue 的名字。
参数 funcindex 与 n 和 lua_getupvalue 中的一样(参见 lua_getupvalue)。
当索引大于 upvalue 的个数时,返回 NULL (什么也不弹出)。
*/
----------------------------------------------------------------------------------


lua_Alloc lua_getallocf (lua_State *L, void **ud){}
/* 返回给定状态机的内存分配器函数
如果 ud 不是 NULL ,Lua 把调用lua_newstate 时传入的那个指针放入*ud 
*/
----------------------------------------------------------------------------------


void lua_getfenv (lua_State *L, int index){}
/* 把索引处值index的环境表压入堆栈
栈+1
*/
----------------------------------------------------------------------------------


void lua_getglobal (lua_State *L, const char *name){}
/* 把全局变量 name 里的值压入堆栈
#define lua_getglobal(L,s)  lua_getfield(L, LUA_GLOBALSINDEX, s)


栈高 +1
*/
----------------------------------------------------------------------------------


int lua_getmetatable (lua_State *L, int index){}
/* 把给定索引指向的值的元表压入堆栈
如果索引无效,或是这个值没有元表,函数将返回 0 并且不会向栈上压任何东西


栈高 +1 或者 不变
*/
----------------------------------------------------------------------------------


int lua_gettop (lua_State *L){}
/* 返回栈顶元素的索引

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值