lua堆棧

http://blog.csdn.net/perfect2011/article/details/19200511

首先了解下c++與lua之間的通信:
假設在一個lua文件中有如下定義
-- hello.lua 文件
myName = "beauty girl"
lua的堆棧(摘要) -     哃步呼吸 - 留住來去無影的思緒

請注意紅色數字,代表通信順序:

1) C++想獲取LuamyName字符串的值,所以它把myName放到Lua堆棧(棧頂),以便Lua能看到

2) Lua從堆棧(棧頂)中獲取myName,此時棧頂再次變爲空

3) Lua拿着這個myNameLua全局表查找myName對應的字符串

4) 全局表返回一個字符串”beauty girl”

5) Lua把取得的“beauty girl”字符串放到堆棧(棧頂)

6) C++可以從Lua堆棧中取得“beauty girl


若有9個元素分別入棧,則:

1. 正數索引,棧底是1,然後一直到棧頂是逐漸+1,最後變成99大於1

2. 負數索引,棧底是-9,然後一直到棧頂是逐漸+1,最後變成-1-1大於-9


索引相關:

1. 正數索引,不需要知道棧的大小,我們就能知道棧底在哪,棧底的索引永遠是1

2. 負數索引,不需要知道棧的大小,我們就能知道棧頂在哪,棧頂的索引永遠是-1


table類型入棧情況(原文地址http://blog.csdn.net/musicvs/article/details/8445079

獲取table變量

現在,我們給helloLua.lua文件添加一個table全局變量:

  1. -- helloLua.lua文件  
  2. myName = "beauty girl"  
  3.   
  4. helloTable = {name = "mutou", IQ = 125}  


 

我們看到,多了一個helloTable的變量,它和數組十分相似,又和HashMap有點類似,總之它很強大。

話說,125乘以2等於多少?...250 ....O O

獲取helloTable變量的方式和以前是一樣的:

  1. /* 取得table變量,在棧頂 */  
  2.     lua_getglobal(pL, "helloTable");  


 

這樣,helloTable變量就被存放到棧頂。

可我們並不是要取table變量,因爲C++中是無法識別Luatable類型的,所以我們要取得table中具體的值,也就是nameIQ的值。

 

 lua_gettable函數

有一個和lua_getglobal類似的函數,叫做lua_gettable,顧名思義,它是用來取得table相關的數據的。

 

lua_gettable函數會從棧頂取得一個值,然後根據這個值去table中尋找對應的值,最後把找到的值放到棧頂。

lua_pushstring()函數可以把C++中的字符串存放到Lua的棧裏;

然後再用lua_gettable()取執行前面所說的步驟,lua_gettable的第二個參數是指定的table變量在棧中的索引。

 

爲了照顧旁白這個笨蛋,我們畫個圖來理解:

這是初始狀態,堆棧裏還沒有任何東西,那麼,現在要先把helloTable變量放到棧頂:

  1. /* 取得table變量,在棧頂 */  
  2.     lua_getglobal(pL, "helloTable");  


 

然後就變成了這樣:

接着,我們要取得tablename對應的值,那麼,先要做的就是把”name”字符串入棧:

  1. /* 將C++的字符串放到Lua的棧中,此時,棧頂變爲“name”, helloTable對象變爲棧底 */  
  2.     lua_pushstring(pL, "name");  


 

然後變成這樣:

 

注意了,我把棧的索引也加上了,因爲我們即將要使用,這次我們用負數索引(不瞭解負數的索引的朋友請閱讀第03章的教程哈~)。

由於”name”的入棧,現在helloTable變量已經不在棧頂了。

接着,我們調用要做最重要的一步了,取得nametable中對應的值:

  1. /*  
  2.         從table對象尋找“name”對應的值(table對象現在在索引爲-2的棧中,也就是當前的棧底), 
  3.         取得對應值之後,將值放回棧頂 
  4.     */  
  5.     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字符串的指針保存到訪問他們的外部函數中。


轉載自:http://wind-catalpa.blog.163.com/blog/static/1147535432013119103150929/



給出Lua虛擬機的體系結構圖(根據源代碼分析得出):
lua architecture
首先, 我們注意到, Lua的解釋器還是一個以棧爲中心的結構. 在lua_State這個結構中,有許多個字段用於描述這個結構.stack用於指向絕對棧底, 而base指向了當前正在執行的函數的第一個參數, 而top指向棧頂的第一個空元素.

發佈了6 篇原創文章 · 獲贊 7 · 訪問量 163萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章