zoukankan      html  css  js  c++  java
  • c调用 lua 栈操作

    转自https://www.cnblogs.com/ringofthec/archive/2010/10/22/lua.html

    打算记录一些lua_api, 可能会觉得lua文档中已经说的很清楚了, 但是我将用自己的方式, 记录下我认为重要的东西, 先约定一下api说明的格式

    编号. api作用简述

    api函数原型

    api操作说明

    返回值说明

    对栈的影响

    注意事项

    1.  建一个新表

    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) 常用这个
     
    2. 取表中的元素

      https://www.cnblogs.com/chuanwei-zhang/p/4077247.html
      void lua_gettable (lua_State *L, int index);
      把t[k] 值压入堆栈,这里的 t 是指有效索引 index 指向的值,而 k 则是栈顶放的值。这个函数会弹出堆栈上的 key,把结果放在栈上相同位置

    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 元方法
     
    3. 给表中的元素赋值
    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 元方法
     
    4. 取表元素 和 表元素赋值
    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 元方法
     
    5. 对table的一些操作[不引发原方法]
    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弹出

    不触发相应的元方法

    6. 复制栈上元素并压入栈

    void lua_pushvalue (lua_State *L, int index)

    操作:   value = Stack[index]       

           Stack.push(value)

    无返回值

    栈+1 

    7. 创建一个元表

    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, 栈顶元素是在注册表中注册过的新表
     
    8. 创建C值
    void *lua_newuserdata (lua_State *L, size_t size)

    该函数分配一块由size指定大小的内存块, 并放在栈顶

    返回值是新分配的块的地址

    栈+1, 栈顶是userdata

    userdata用来在lua中表示c中的值. 一个完整的userdata有自己的元表, 在垃圾回收时, 可以调用它的元表的__gc方法

    9. 注册c函数到lua中, 其实没有这回事, lua中只有c闭包

    void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n)

    向栈上压一个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))

    没有返回值

    栈不变化

    这个是比较常用的, 以n为lua中的key压入一个0个绑定值的cclosure.

  • 相关阅读:
    【Leetcode】23. Merge k Sorted Lists
    【Leetcode】109. Convert Sorted List to Binary Search Tree
    【Leetcode】142.Linked List Cycle II
    【Leetcode】143. Reorder List
    【Leetcode】147. Insertion Sort List
    【Leetcode】86. Partition List
    jenkins 配置安全邮件
    python 发送安全邮件
    phpstorm 同步远程服务器代码
    phpUnit 断言
  • 原文地址:https://www.cnblogs.com/taek/p/8380178.html
Copyright © 2011-2022 走看看