LuaAPI finishing

ref: https://blog.csdn.net/ouyangshima/article/details/43339571

  • size_t l = lua_strlen (L, -1); // its length
  • assert(s[l] == ‘’);

  • assert (strlen(s) <= l);

  • Lua data is passed to the virtual stack

      < li>

      /*get functions (Lua -> stack)——>Operation between Lua space and virtual stack

    1. LUA_API void (lua_gettable) (lua_State *L, int idx);//把t[k] 值压入堆栈,这里的t 是指有效索引index 指向的值,而k 则是栈顶放的值。这个函数会弹出堆栈上的 key (把结果放在栈上相同位置)。在 Lua 中,这个函数可能触发对应 “index” 事件的元方法

    2. lua_getglobal(L, “mytable”) <== push mytable

    3. lua_pushnumber(L, 1) <== push key 1

    4. lua_gettable(L, -2) <== pop key 1, push mytable[1]

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

    7. lua_getglobal(L, “mytable”) <== push mytable

    8. lua_getfield(L, -1, “x”) <== push mytable["x"],作用同下面两行调用

    9. –lua_pushstring(L, “x”) <== push key "x"

    10. –lua_gettable(L,-2) <== pop key "x", push mytable["x"]

    11.  
    12. LUA_API void (lua_rawget) (lua_State *L, int idx);//类似于 Lua_gettable,但是作一次直接访问(不触发元方法)。

    13. LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);//把 t[n] 的值压栈,这里的 t 是指给定索引 index 处的一个值。这是一个直接访问;就是说,它不会触发元方法。

    14. lua_getglobal(L, “mytable”) <== push mytable

    15. lua_rawgeti(L, -1, 1) <== push mytable[1],作用同下面两行调用

    16. –lua_pushnumber(L, 1) <== push key 1

    17. –lua_rawget(L,-2) <== pop key 1, push mytable[1]

    18.  
    19. LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);//创建一个新的空 table 压入堆栈。这个新 table 将被预分配 narr 个元素的数组空间以及 nrec 个元素的非数组空间。当你明确知道表中需要多少个元素时,预分配就非常有用。如果你不知道,可以使用函数 Lua_newtable。

    20.  
    21. LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);//这个函数分配分配一块指定大小的内存块,把内存块地址作为一个完整的 userdata 压入堆栈,并返回这个地址。

    22. userdata 代表 Lua 中的 C 值。完整的 userdata 代表一块内存。它是一个对象(就像 table 那样的对象):你必须创建它,它有着自己的元表,而且它在被回收时,可以被监测到。一个完整的 userdata 只和它自己相等(在等于的原生作用下)。

    23. 当 Lua 通过 gc 元方法回收一个完整的 userdata 时, Lua 调用这个元方法并把 userdata 标记为已终止。等到这个 userdata 再次被收集的时候,Lua 会释放掉相关的内存。

    24. LUA_API int (lua_getmetatable) (lua_State *L, int objindex);//把给定索引指向的值的元表压入堆栈。 If the index is invalid, or there is no metatable for this value, the function will return 0 and nothing will be pushed onto the stack.

    25. LUA_API void (lua_getfenv) (lua_State *L, int idx);//把索引处值的环境表压入堆栈。

    26. */

    虚拟栈数据传递到Lua空间中

    1. /*set functions (stack -> Lua)——>Lua空间与虚拟栈之间的操作

    2.  
    3. LUA_API void (lua_settable) (lua_State *L, int idx);作一个等价于 t[k] = v 的操作,这里 t 是一个给定有效索引 index 处的值, v 指栈顶的值,而 k 是栈顶之下的那个值。这个函数会把键和值都从堆栈中弹出。和在 Lua 中一样,这个函数可能触发 “newindex” 事件的元方法。 eg:

    4. lua_getglobal(L, “mytable”) <== push mytable

    5. lua_pushnumber(L, 1) <== push key 1

    6. lua_pushstring(L, “abc”) <== push value "abc"

    7. lua_settable(L, -3) <== mytable[1] = "abc", pop key & value

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

    10. lua_getglobal(L, “mytable”) <== push mytable

    11. lua_pushstring(L, “abc”) <== push value "abc"

    12. lua_setfield(L, -2, “x”) <== mytable["x"] = "abc", pop value "abc"

    13.  
    14. LUA_API void (lua_rawset) (lua_State *L, int idx);//类似于 Lua_settable,但是是作一个直接赋值(不触发元方法)。

    15. LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);//等价于 t[n] = v,这里的 t 是指给定索引 index 处的一个值,而 v 是栈顶的值。函数将把这个值弹出栈。赋值操作是直接的;就是说,不会触发元方法。

    16. lua_getglobal(L, “mytable”) <== push mytable

    17. lua_pushstring(L, “abc”) <== push value "abc"

    18. lua_rawseti(L, -2, 1) <== mytable[1] = "abc", pop value "abc"

    19.  
    20. LUA_API int (lua_setmetatable) (lua_State *L, int objindex);//把一个 table 弹出堆栈,并将其设为给定索引处的值的 metatable 。

    21. LUA_API int (lua_setfenv) (lua_State *L, int idx);//从堆栈上弹出一个 table 并把它设为指定索引处值的新环境。如果指定索引处的值即不是函数又不是线程或是 userdata , Lua_setfenv 会返回 0 ,否则返回 1 。

    22. */

    虚拟栈基本操作

    1. /* basic stack manipulation–基础栈操作

    2. LUA_API int (lua_gettop) (lua_State *L);//获取栈的高度,它也是栈顶元素的索引。注意一个负数索引-x对应于正数索引gettop-x+1

    3. LUA_API void (lua_settop) (lua_State *L, int idx);//设置栈的高度。如果开始的栈顶高于新的栈顶,顶部的值被丢弃。否则,为了得到指定的大小这个函数压入相应个数的空值(nil)到栈上。特别的,lua_settop(L,0)清空堆栈。

    4. LUA_API void (lua_pushvalue) (lua_State *L, int idx);//压入堆栈上指定索引的一个抟贝到栈顶,【增加一个元素到栈顶】

    5. LUA_API void (lua_remove) (lua_State *L, int idx);//移除指定索引位置的元素,并将其上面所有的元素下移来填补这个位置的空白,【删除了一个元素】

    6. LUA_API void (lua_insert) (lua_State *L, int idx);//移动栈顶元素到指定索引的位置,并将这个索引位置上面的元素全部上移至栈顶被移动留下的空隔,【没有增加一个元素,移动了元素的位置】

    7. LUA_API void (lua_replace) (lua_State *L, int idx);//从栈顶弹出元素值并将其设置到指定索引位置,没有任何移动操作。 【删除了一个元素,替换掉指定的元素】

    8. LUA_API int (lua_checkstack) (lua_State *L, int sz);//检查栈上是否有能插入n个元素的空间;没有返回0

    9. LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);//将一个堆栈上的从栈顶起的n个元素 移到另一个堆栈上

    10.  
    11. lua的堆栈保持着后进先出的原则。如果栈开始于 10 20 30 40 50*(自底向上;`*´ 标记了栈顶),那么:

    12. lua_pushvalue(L, 3)    –> 10 20 30 40 50 30*

    13. lua_pushvalue(L, -1)   –> 10 20 30 40 50 30 30*

    14. lua_remove(L, -3)      –> 10 20 30 40 30 30*

    15. lua_remove(L, 6)      –> 10 20 30 40 30*

    16. lua_insert(L, 1)      –> 30 10 20 30 40*

    17. lua_insert(L, -1)      –> 30 10 20 30 40* (no effect)

    18. lua_replace(L, 2)      –> 30 40 20 30*

    19. lua_settop(L, -3)      –> 30 40*

    20. lua_settop(L, 6)      –> 30 40 nil nil nil nil*

    21. */

    宏定义

    1. /* some useful macros

    2. #define lua_pop(L,n) lua_settop(L, -(n)-1)

    3. #define lua_newtable(L) lua_createtable(L, 0, 0)

    4. #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))

    5. #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)

    6. #define lua_strlen(L,i) lua_objlen(L, (i))

    7.  
    8. #define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)

    9. #define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)

    10. #define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)

    11. #define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)

    12. #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)

    13. #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)

    14. #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)

    15. #define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)

    16.  
    17. #define lua_pushliteral(L, s) lua_pushlstring(L, “” s, (sizeof(s)/sizeof(char))-1)

    18. #define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))

    19. #define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))

    20. #define lua_tostring(L,i) lua_tolstring(L, (i), NULL)

    21.  
    22.  
    23. //compatibility macros and functions

    24. #define lua_open() luaL_newstate()
    25. #define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)

    26. #define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)

    27. #define lua_Chunkreader lua_Reader

    28. #define lua_Chunkwriter lua_Writer

    29. */

     

     

    1. /*