請注意紅色數字,代表通信順序:
1) C++想獲取Lua的myName字符串的值,所以它把myName放到Lua堆棧(棧頂),以便Lua能看到
2) Lua從堆棧(棧頂)中獲取myName,此時棧頂再次變爲空
3) Lua拿着這個myName去Lua全局表查找myName對應的字符串
4) 全局表返回一個字符串”beauty girl”
5) Lua把取得的“beauty girl”字符串放到堆棧(棧頂)
6) C++可以從Lua堆棧中取得“beauty girl”
若有9個元素分別入棧,則:
1. 正數索引,棧底是1,然後一直到棧頂是逐漸+1,最後變成9(9大於1)
2. 負數索引,棧底是-9,然後一直到棧頂是逐漸+1,最後變成-1(-1大於-9)
1. 正數索引,不需要知道棧的大小,我們就能知道棧底在哪,棧底的索引永遠是1
2. 負數索引,不需要知道棧的大小,我們就能知道棧頂在哪,棧頂的索引永遠是-1
table類型入棧情況(原文地址:http://blog.csdn.net/musicvs/article/details/8445079)
獲取table變量
現在,我們給helloLua.lua文件添加一個table全局變量:
- -- helloLua.lua文件
- myName = "beauty girl"
- helloTable = {name = "mutou", IQ = 125}
我們看到,多了一個helloTable的變量,它和數組十分相似,又和HashMap有點類似,總之它很強大。
話說,125乘以2等於多少?...250 ....O O!
獲取helloTable變量的方式和以前是一樣的:
- /* 取得table變量,在棧頂 */
- lua_getglobal(pL, "helloTable");
這樣,helloTable變量就被存放到棧頂。
可我們並不是要取table變量,因爲C++中是無法識別Lua的table類型的,所以我們要取得table中具體的值,也就是name和IQ的值。
lua_gettable函數
有一個和lua_getglobal類似的函數,叫做lua_gettable,顧名思義,它是用來取得table相關的數據的。
lua_gettable函數會從棧頂取得一個值,然後根據這個值去table中尋找對應的值,最後把找到的值放到棧頂。
lua_pushstring()函數可以把C++中的字符串存放到Lua的棧裏;
然後再用lua_gettable()取執行前面所說的步驟,lua_gettable的第二個參數是指定的table變量在棧中的索引。
爲了照顧旁白這個笨蛋,我們畫個圖來理解:
這是初始狀態,堆棧裏還沒有任何東西,那麼,現在要先把helloTable變量放到棧頂:
- /* 取得table變量,在棧頂 */
- lua_getglobal(pL, "helloTable");
然後就變成了這樣:
接着,我們要取得table的name對應的值,那麼,先要做的就是把”name”字符串入棧:
- /* 將C++的字符串放到Lua的棧中,此時,棧頂變爲“name”, helloTable對象變爲棧底 */
- lua_pushstring(pL, "name");
然後變成這樣:
注意了,我把棧的索引也加上了,因爲我們即將要使用,這次我們用負數索引(不瞭解負數的索引的朋友請閱讀第03章的教程哈~)。
由於”name”的入棧,現在helloTable變量已經不在棧頂了。
接着,我們調用要做最重要的一步了,取得name在table中對應的值:
- /*
- 從table對象尋找“name”對應的值(table對象現在在索引爲-2的棧中,也就是當前的棧底),
- 取得對應值之後,將值放回棧頂
- */
- lua_gettable(pL, -2);
此時,棧變成這樣:
lua_gettable倒底做了什麼事情?
首先,我們來解釋一下lua_gettable的第二個參數,-2是什麼意思,-2就是剛剛helloTable變量在棧中的索引。
然後,Lua會去取得棧頂的值(之前的棧頂是”name”),然後拿着這個值去helloTable變量中尋找對應的值,當然就找到”mutou”了。
最後,Lua會把找到的值入棧,於是”mutou”就到了棧頂了。
這樣仍然需要不同的函數將每種C類型的值壓入棧和一個從不同函數從棧上取值(並不彈出)。
使用lua_push*(lua_State * L,x)壓棧,
使用lua_to*(lua_State * L,棧中位置)取值,
使用lua_pop(lua_State * L,出棧個數)出棧。
Lua_tostring函數返回一個指向字符串的內部拷貝的指針。你不能修改它(使你想起那裏有一個const)。只要這個指針對應的值還在棧內,Lua會保證這個指針一直有效。當一個C函數返回後,Lua會清理他的棧,所以,有一個原則:永遠不要將指向Lua字符串的指針保存到訪問他們的外部函數中。