c呼叫 lua 棧操作

2022-03-10 22:33:50 字數 4100 閱讀 3887

**

打算記錄一些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. 取表中的元素

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.

Lua操作棧c呼叫lua

include stdafx.h int main 得到初始化棧大小 printf 初始化棧大小 d n lua gettop plua 開啟所有功能庫 lual openlibs plua 載入指令碼 lual dofile plua,test.lua 將指令碼中的add函式入棧 int ret ...

lua與C(一) C呼叫lua

lua和c有兩種關係 一種是在lua中呼叫c的函式,c稱為庫 一種是c中呼叫lua,c就稱為應用程式 此時c中包含了lua的直譯器 c 部分 注意在c 中,通常要把lua的一些標頭檔案定義在extern c 中,因為他們是c語言實現的。1.作為應用程式呼叫lua char buffer print ...

C 呼叫lua例子

huangxw3 ubuntu cat add.lua function add x,y return x y end huangxw3 ubuntu cat main.cpp include include extern c using namespace std lua state l int ...