一、Lua堆棧
要理解Lua和C++交互,首先要理解Lua堆棧。
簡單來說,Lua和C/C++語言通信的主要方法是一個無處不在的虛擬棧。棧的特點是先進後出。
在Lua中,Lua堆棧就是一個struct,堆棧索引的方式可是是正數也可以是負數,區別是:正數索引1永遠表示棧底,負數索引-1永遠表示棧頂。如圖:
lua的棧類似於以下的定義, 它是在創建lua_State的時候創建的:
TValue stack[max_stack_len] // 欲知內情可以查 lstate.c 的stack_init函數存入棧的數據類型包括數值, 字符串, 指針, talbe, 閉包等, 下面是一個棧的例子:
執行下面的代碼就可以讓你的lua棧上呈現圖中的情況
lua_pushcclosure(L, func, 0) // 創建並壓入一個閉包
lua_createtable(L, 0, 0) // 新建並壓入一個表
lua_pushnumber(L, 343) // 壓入一個數字
lua_pushstring(L, “mystr”) // 壓入一個字符串
這裡要說明的是, 你壓入的類型有數值, 字符串, 表和閉包[在c中看來是不同類型的值], 但是最後都是統一用TValue這種數據結構來保存的:), 下面用圖簡單的說明一下這種數據結構:
TValue結構對應於lua中的所有數據類型, 是一個{值, 類型} 結構, 這就lua中動態類型的實現, 它把值和類型綁在一起, 用tt記錄value的類型, value是一個聯合結構, 由Value定義, 可以看到這個聯合有四個域, 先說明簡單的
p -- 可以存一個指針, 實際上是lua中的light userdata結構 n -- 所有的數值存在這裡, 不過是int , 還是float b -- Boolean值存在這裡, 注意, lua_pushinteger不是存在這裡, 而是存在n中, b只存布爾 gc -- 其他諸如table, thread, closure, string需要內存管理垃圾回收的類型都存在這裡 gc是一個指針, 它可以指向的類型由聯合體GCObject定義, 從圖中可以看出, 有string, userdata, closure, table, proto, upvalue, thread
從下面的圖可以的得出如下結論:
1. lua中, number, boolean, nil, light userdata四種類型的值是直接存在棧上元素裡的, 和垃圾回收無關.
2. lua中, string, table, closure, userdata, thread存在棧上元素裡的只是指針, 他們都會在生命周期結束後被垃圾回收.