lua5.1函数解析

lua中文文档(风云)地址:https://www.codingnow.com/2000/download/lua_manual.html#lua_CFunction

1.lua_newtable

//创建一个空 table ,并将之压入堆栈。 它等价于 lua_createtable(L, 0, 0) 。
void lua_newtable (lua_State *L);

2. lua_setfield

//做一个等价于 t[k] = v 的操作, 这里 t 是给出的有效索引 index 处的值, 而 v 是栈顶的那个值。
//这个函数将把这个值弹出堆栈。 跟在 Lua 中一样,这个函数可能触发一个 "newindex" 事件的元方法 。
void lua_setfield (lua_State *L, int index, const char *k);

eg:

   lua_newtable(L);
   lua_pushcfunction(L, lfunctimer_new_hook);
   lua_setfield(L, -2, "new");

第一行创建个空表 就叫他t
第二行把函数lfunctimer_new_hook 入栈
第三行 由于函数lfunctimer_new_hook 后入栈的 所以第一行中的空表现在在堆栈的-2位置上,所以lua_setfield(L, -2, “new”) 代表把函数lfunctimer_new_hook 赋值给表t的"new"索引下标下 t[“new”]=lfunctimer_new_hook ,表t现在在栈顶的位置。

3.lua_getfield

//把 t[k] 值压入堆栈, 这里的 t 是指有效索引 index 指向的值。 在 Lua 中,这个函数可能触发对应 "index" 事件的元方法
void lua_getfield (lua_State *L, int index, const char *k);

ps:它与lua_setfield 函数相反,它是指把栈索引index处指向的值的下标k处的值压入栈顶

4.lua_settop

//参数允许传入任何可接受的索引以及 0 。 它将把堆栈的栈顶设为这个索引。 如果新的栈顶比原来的大,超出部分的新元素将被填为 nil 。 如果 index 为 0 ,把栈上所有元素移除。
void lua_settop (lua_State *L, int index);

eg:

lua_settop(L, 3);

从栈底到栈顶的顺序,保留3个栈的数据,如果栈里存在超过3个数据,超过的部分会被移除,如果栈里数据低于3个,会填充nil到栈顶,补齐到3个数据

5.lua_pushcclosure

//把一个新的 C closure 压入堆栈。
//当创建了一个 C 函数后,你可以给它关联一些值,这样就是在创建一个 C closure (参见 §3.4); 接下来无论函数何时被调用,这些值都可以被这个函数访问到。 为了将一些值关联到一个 C 函数上, 首先这些值需要先被压入堆栈(如果有多个值,第一个先压)。 接下来调用 lua_pushcclosure 来创建出 closure 并把这个 C 函数压到堆栈上。 参数 n 告之函数有多少个值需要关联到函数上。 lua_pushcclosure 也会把这些值从栈上弹出。
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);

6.lua_pushcfunction

//将一个 C 函数压入堆栈。 这个函数接收一个 C 函数指针,并将一个类型为 function 的 Lua 值 压入堆栈。当这个栈顶的值被调用时,将触发对应的 C 函数。
//注册到 Lua 中的任何函数都必须遵循正确的协议来接收参数和返回值 
void lua_pushcfunction (lua_State *L, lua_CFunction f);
//lua_pushcfunction 是作为一个宏定义出现的
 #define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)

7.require (modname)

加载给定的模块。该函数首先查看 package.loaded 表以确定 modname 是否已加载。如果是,则 require 返回存储在 package.loaded[modname] 中的值。否则,它会尝试为模块查找加载器。

要找到加载器,首先需要查询 package.preload[modname]。如果它有一个值,这个值(应该是一个函数)就是加载器。否则需要使用存储在 package.path 中的路径搜索 Lua 加载器。如果这也失败了,它会使用存储在 package.cpath 中的路径来搜索 C 加载器。如果这也失败了,它会尝试一个多合一的加载器(见下文)。

加载 C 库时,require 首先使用动态链接工具将应用程序与库链接。然后它试图在这个库中找到一个 C 函数作为加载器。此 C 函数的名称是字符串“luaopen_”与模块名称的副本连接,其中每个点都被下划线替换。此外,如果模块名称有一个连字符,它的前缀直到(包括)第一个连字符被删除。例如,如果模块名称是 a.v1-b.c,则函数名称将是 luaopen_b_c。

如果 require 既没有找到 Lua 库也没有找到模块的 C 库,它会调用 all-in-one loader。此加载程序在 C 路径中搜索给定模块的根名称的库。例如,当需要 a.b.c 时,它会在 C 库中搜索 a。如果找到,它会在其中查找子模块的打开函数;在我们的示例中,这将是 luaopen_a_b_c。有了这个功能,一个包可以将几个 C 子模块打包到一个库中,每个子模块都保持其原始的开放功能。

找到加载器后,require 使用单个参数 modname 调用加载器。如果加载器返回任何值,require 将返回的值分配给 package.loaded[modname]。如果加载器没有返回值并且没有为 package.loaded[modname] 分配任何值,则 require 将 true 分配给该条目。在任何情况下,require 都会返回 package.loaded[modname] 的最终值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值