<span style="background-color: rgb(255, 255, 255); font-family: Arial, Helvetica, sans-serif;">這篇爲學習lua雜記。</span>
一、關於lua源碼的一些文件:
1.lua.c —— lua解釋器程序源碼。
2.lua.h —— 該頭文件定義了Lua提供的基礎函數,包括創建Lua環境,調用Lua函數(如 lua_pcall)、讀寫Lua環境中全局變量,
以及註冊供Lua調用的新函數等。該頭文件定義所有內容都有一個“lua_”前綴。
3.luaxlib.h —— 該頭文件定義了Lua輔助庫提供的函數。他的所有定義都以“luaL_”爲前綴(如 luaL_loadbuffer)。輔助庫是一個
使用lua.h中的API編寫出來的一個較高的抽象層。注:輔助庫沒有直接訪問Lua內部,它都是官方的基礎API來完成
所有工作的。
二、關於lua的一些函數:
1.luaL_newstate() —— 創建一個新的Lua環境(或狀態)。當創建一個新的環境時,該環境爲空,新環境中沒有包含預定義的函數。
爲了使Lua保持小巧,所有標準庫都被組織到了不同的包中。在lualib.h中定義了打開這些庫的函數。
2.luaL_openlibs (lua_State *L) —— 該函數可以打開所有的標準庫。
3.luaL_loadbuffer(L,s,sz,n) —— 編譯加載到Lua環境中的命令。如果沒有錯誤,此函數返回0,並想棧中壓入編譯後的程序塊。
4.lua_pcall(L,n,r,f) —— 通過調用此函數,將luaL_loadbuffer()壓入棧中的程序塊彈出,並在保護模式中運行它。與luaL_loadbuffer
一樣,該函數返回0表示沒有錯誤。如果發生錯誤,那麼這些函數就會向棧中壓入一條錯誤消息。
對於lua_pcall函數的參數的一些補充,第一個參數就是Lua環境,第二個參數爲函數需要傳入幾個參數,第三個爲函數返回幾個參數,第四個
則爲出錯後調用錯誤函數的索引,這個函數必須存在在棧中。
詳細:http://www.360doc.com/content/12/0529/19/1317564_214572845.shtml
5.lua_tostring(L,i) —— 用該函數可以獲取lua_pcall調用的函數錯誤時向棧中壓入的一條錯誤信息。打印後,
可以用lua_pop()把它從棧中刪除。
三、關於棧的一些基礎理解:
一、關於對棧操作的一些函數:
①.壓棧操作函數
1.void lua_pushnil (lua_State *L) —— 向棧中壓入常量nil值。
2.lua_pushnumber(lua_State *L) ——向棧中壓入雙精度浮點數。
3.lua_pushinteger(lua_State *L) —— 向棧中壓入整型數。
4.lua_pushboolean(lua_State *L) —— 向棧中壓入bool變量(C語言中用整數)。
5.lua_pushlstring(lua_State *L) —— 向棧中壓入字符串(char * 及長度)。
6.lua_pushstring(lua_State *L) —— 向棧中壓入以字符零結尾的字符串。
7.int lua_checkstack(lua_State *L, int sz) —— 檢查棧是否夠用。
③.查詢棧中元素
在Lua通訊中,向棧查詢元素是通過索引(index),正索引是從第一個壓入參數開始,負索引是從最後一個
壓入參數開始。
1. int lua_is*(lua_State *L, int index) —— 此類函數是查詢棧中元素是否是查詢的類型。
需要注意的是:lua_isnumber不會檢查值是否是數字類型,而是檢查值是否能轉換爲數字類型,lua_isstring也具有
同樣的行爲。因此,對於任何數字,lua_isstring都返回真。
2.int lua_type (lua_State *L, int idx) —— 該函數返回戰洪元素的類型。每種類型都對應一個常量,這些常量定義在頭文件lua.h中。
注意:
該函數一般可用在一個switch語句中。另外,若要檢查一個元素是否爲真正的字符串或數字(無需轉換的),也可以使用換個函數。
lua_type 返回類型常量定義如圖:
3.lua_to*系類函數用於從棧中獲取一個值,函數原型如圖:
注:當Lua調用一個C函數返回時,Lua就會清空它的棧。所以,不要在C函數之外使用在C函數內獲得的指向Lua字符串的指針。
④.其他對棧操作的函數:
1.int lua_gettop (lua_State *L) —— 該函數返回棧中元素的個數,也可以說是棧頂的索引。
2.void lua_settop (lua_State *L, int idx) —— 將棧頂設置爲一個指定的位置,如果之前的棧頂比新設置的更高,那麼搞出來的就被丟棄;
反之,會向棧中壓入nil來不足大小。即修改棧中元素的數量。有一個特殊的調用, lua_settop (L, 0)能清空棧。在Lua中還定義了一個
特殊的宏:#define lua_pop(L,n) lua_settop(L, -(n)-1)
3.void lua_pushvalue (lua_State *L, int idx) —— 該函數會將指定索引上的值的副本壓入棧。即,把堆棧上給定有效處索引處的元素作一
個拷貝壓棧。
4.void lua_remove (lua_State *L, int idx) —— 該函數刪除索引上的元素,並將該索引以上的元素下移以填補空缺。
5.void lua_insert (lua_State *L, int idx) —— 該函數會上移指定位置上的所有元素以開闢一個槽的空間,然後將棧頂元素移到該位置。
6.void lua_replace (lua_State *L, int idx) —— 函數會把棧頂元素移動到給定位置(並且把這個棧頂元素彈出), 不移動任何元素(因
此在那個位置處的值被覆蓋掉)。
注:
lua_settop(L,-1) 和lua_insert (L,-1)不會對棧產生影響。
lua_settop(L,-1) 爲將棧頂元素設置爲它當前值。
lua_insert (L,-1)爲將棧頂元素移動到棧頂
添加新的一個基礎連接,寫的很詳細,謝謝作者:http://cn.cocos2d-x.org/tutorial/show?id=1474
==================================華麗分割線================20140911==================
一、所爲Lua通訊,其實就是對棧的各種操作。
由此博客學習:Lua和C++交互總結(很詳細)
測試是通過修改C/C++調用lua函數代碼改動的。
1.修改test.lua,添加自己的變量,代碼如下:
mystring = "I love U";
val = 100;
tab1 = {name = "dongge", id = "250"};
function add(x,y)
return x + y;
end
2.向main.cpp中添加函數:
int GetValFromLua(lua_State *L)
{
/*獲取變量方法*/
lua_getglobal(L,"mystring");
string str = lua_tostring(L,-1);
cout<<"mystring:"<<str.c_str()<<endl;
/*獲取表*/
lua_getglobal(L,"tab1");
lua_getfield(L,-1,"name");
str = lua_tostring(L,-1);
cout<<"table:name:"<<str.c_str()<<endl;
return 0;
}
向main函數添加調用函數代碼:
GetValFromLua(L);
測試是否對棧進行彈出操作:
lua_getfield(L,2,"name");
string test = lua_tostring(L,-1);
cout<<"ceshi:"<<test.c_str()<<endl;
源代碼下載:點擊此處
對於lua_pcall的個人理解:
/*通過名字獲取Lua函數*/
lua_getglobal(L,"add");//這只是向棧中壓入函數名稱
/*向棧中壓入第一個參數*/
cout<<"First push stack x is :"<<x<<endl;
lua_pushnumber(L,x);//向棧中壓入參數
/*向棧中壓入第二個參數*/
cout<<"Second push stack y is :"<<y<<endl;
lua_pushnumber(L,y);//向棧中壓入參數
/*調用函數*/
//lua_call(L,2,1);
lua_pcall(L, 2, 1, 0);//執行過程中先將棧中向函數add傳入的參數彈棧,\
將函數名彈棧,找到對應的函數,執行函數,然後將函數返回\
此時棧中的函數名和向函數傳入的參數都已出棧,也就是沒有了\
如果前面沒有對棧進行任何操作,此時棧中的數據只有一個就是棧頂,\
add函數的返回值。
希望大家多多指正,共同進步。
每天進步一點點。。。