接下来调用 lua_pushcclosure 来创建出 closure 并把这个 C 函数压到堆栈上。参数 n 告之函数有多少个值需要关联到函数上。 lua_pushcclosure 也会把这些值从栈上弹出。 eg. #define lua_register(l,n,f) (lua_pushcfunction(l,f), lua_setglobal(l,n)) #lua_pushcfunction(l,f) lua_pushcclosur...
lua_pushcclosure函数会先创建一个CClosure结构,然后把提前push到栈顶的n个元素作为upvalue,将其引用存储在CClosure的upvalue数组中。 可见在堆栈调用这一方面来看,CClosure和LClosure没有什么区别。二者的最大区别,在于LClosure是需要去解析lua文件来得到upvalue以及字节码等信息,在执行时需要去根据opcode来执行;而CClos...
C中通过lua_pushclosure创建闭包函数,在将闭包函数推到堆栈之前需要先把n个上值推到lua_state上。取用的时使用lua_upvalueindex(n)取的特定索引上的上值,更改的话可以使用lua_replace更改上值。例子中每次将上值+5,因此在lua中每次调用upvalue_test函数都会获得正确的上值。lua中的closure想在C中进行upvalue的更改...
上面的代码很简单,就是先push进去一个整数0,然后再push一个closure,这里closure的第三个参数就是upvalue的个数(这里要注意在lua中的upvalue的个数只有一个字节,因此你太多upvalue会被截断)。 lua_pushcclosure的代码前面已经分析过了,我们这里简单的再介绍一下。 这个函数每次都会新建一个closure,然后将栈上的对应的...
lua_pushboolean## 原型:void lua_pushboolean (lua_State *L, int b); 解释:把 b 作为一个 boolean 值压入堆栈。 lua_pushcclosure## 原型:void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); 解释:把一个新的 C closure 压入堆栈。
向lua中注册c函数的过程是通过lua_pushcclosure(L, f, n)函数实现的 流程: 1. 创建一个 sizeof(CClosure) + (n - 1) * sizeof(TValue)大小的内存, 这段内存是 CClosure + TValue[n], 并做gc簿记[这点太重要了, 为什么lua要控制自己世界中的所有变量, 就是因为它要做gc簿记来管理内存], isC=...
7行:lua_pushcclosure创建一个C闭包,这时的栈: table|closure 8行:给table设置key,table在栈中的位置是-(nup+2),也就是-2(栈可以用负值从栈顶倒着索引),key名是l->name,value是上面压在栈顶的closure。设置完之后会将值从栈顶移除,此时栈内容是:table。然后继续循环,直到把数组设置完毕。 9行:lua_pop...
向lua中注册c函数的过程是通过lua_pushcclosure(L, f, n)函数实现的 流程: 1. 创建一个 sizeof(CClosure) + (n - 1) * sizeof(TValue)大小的内存, 这段内存是 CClosure + TValue[n], 并做gc簿记[这点太重要了, 为什么lua要控制自己世界中的所有变量, 就是因为它要做gc簿记来管理内存], isC=...
lua_pushcclosure# [-n, +1, e] void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); 把一个新的 C 闭包压栈。 当创建了一个 C 函数后, 你可以给它关联一些值, 这就是在创建一个 C 闭包(参见 §4.4); 接下来无论函数何时被调用,这些值都可以被这个函数访问到。 为了将一些值...
在noita游戏目录\tools_modding\lua_api_documentation.txt文件中写有所有(应该)由cpp声明给lua的函数。 因为是在cpp中定义的,这导致一般来讲我们无法获得其实现。 但是可以通过对游戏文件Noita.exe进行逆向分析(这里使用的是ida),查找可能的实现代码。 在lua与cpp交互中,Nolla选择了使用lua_pushcclosure和lua_setfie...