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(\"hello,lua\")";
lua_State* ls=luaL_newstate();
int error;
luaL_openlibs(ls);
error=luaL_loadbuffer(ls,buffer,strlen(buffer),"line");printError(ls,error,"loaderror");
error=lua_pcall(ls,0,0,0);
printError(ls,error,"callerror");error=luaL_loadfile(ls,"1.lua");
printError(ls,error,"loaderror");
error=lua_pcall(ls,0,0,0);
printError(ls,error,"callerror");lua_close(ls);
getchar();
return ;所有lua相關的東西都儲存在lua_State這個結構中,luaL_loadbuffer
和=luaL_loadfile載入lua程式碼,lua_pcall安全的執行lua程式碼,他將lua程式碼在保護模式下執行,不會導致程式的crash,如果想保護與lua互動的c程式碼,則可以使用lua_cpcall,他接受的是一個c函式
與lua程式碼間訪問交換資料
c和lua之間採用棧的方式交換資料。兩邊程式碼可以使用各種API將資料壓入到一個公用的棧中,或者利用api從這個棧中取出資料。而事實是幾乎所有的api函式都會使用這個棧。棧的空間是有限的,至少有20個。如果c程式碼作為一個庫函式被lua呼叫,在可能出錯的地方要呼叫lua_error,來保證在lua中執行時的安全。
另外這個棧不是一個全域性的概念,每個函式都有自己的區域性私有棧,當lua呼叫一個c函式時,第一個引數總是這個區域性棧的索引1
2 壓入C元素到棧
void pushnil/boolean/number/integer/string/lstring/...這些函式壓入不同型別的資料到棧
壓入一個空表
lua_newtable
設定棧中table的值:
1.先壓入索引key
2.壓入value
3.呼叫lua_settable(Lua_state,index),設定index處的表的[key]=value,注意這個函式結束會彈出key和value
3壓入lua元素到棧
lua_getglobal()將lua中的某個全域性變數壓入棧中
4 從棧中獲取lua元素
int lua_toboolean(luaState *L,int index) 等函式
棧的檢索index正數開始代表從棧地開始的順序,負數代表從棧頂的順序
可以先使用 lua_is*函式檢測這個元素是不是所要型別或lua_type直接得到他的型別
獲取table元素:
1.將元素的key壓入到棧中 lua_pushstring
2.使用lua_gettable(Lua_state,index)這裡index是table的索引,這個函式可以獲取這個table的索引為key的值,注意這個函式結束會彈出key並將value放於棧頂
*對於字串索引,可以用lua_getfield(Lua_state,index,key)來直接獲取
5從棧中獲取元素設定給lua變數
lua_setglobal("L",name) 將棧頂元素給lua的name變數 ,然後彈出棧
6 其他棧操作
lua_gettop得到棧中棧頂的位置,也就是資料的數量 lua_settop設定棧頂元素此外還有insert remove等在棧中間操作的各種操作
7呼叫lua函式
1.壓入lua函式到棧lua_getglobal
2.按引數從左到右順序將c變數作為引數壓入棧
3.使用lua_pcall呼叫lua_pcall(Lua_state,引數個數,返回值個數,錯誤處理函式索引),然後引數和函式被彈出,結果被先後壓入棧
如果出錯,lua_pcall將返回一個非零值,然後壓入一條錯誤訊息到棧