今天繼續學習Lua和C#的互動,今天要講的是載入Lua檔案。 之後的例子都會使用

tolua

來寫,因為tolua提供的lua原生api比xlua更多。

當然你也可以自己編譯lua的dll放到unity裡面。

載入檔案使用的是

luaL_loadfile

這個api,案例如下: 結果是先列印100,再列印200

var

L

=

LuaDLL

luaL_newstate

();

var

path

=

Application

dataPath

+

“/Examples/02_LoadFile/02。lua”

var

errorPath

=

Application

dataPath

+

“/02。lua”

//返回結果不是0代表載入失敗

var

result

=

LuaDLL

luaL_loadfile

L

path

);

//Debug。Log(result);

if

result

!=

0

{

Debug

LogError

LuaDLL

lua_tostring

L

-

1

));

}

if

LuaDLL

lua_pcall

L

0

0

0

!=

0

{

Debug

LogError

LuaDLL

lua_tostring

L

-

1

));

}

LuaDLL

lua_getglobal

L

“a”

);

LuaDLL

lua_getglobal

L

“b”

);

if

LuaDLL

lua_isnumber

L

-

2

==

1

{

Debug

Log

LuaDLL

lua_tonumber

L

,-

2

));

}

if

LuaDLL

lua_isnumber

L

-

1

==

1

{

Debug

Log

LuaDLL

lua_tonumber

L

,-

1

));

}

LuaDLL

lua_close

L

);

Lua程式碼如下:

a = 100

b = 200

Lua裡面暫時不寫函式,關於函式的呼叫會在之後講。

接下來解釋程式碼:

var

result

=

LuaDLL

luaL_loadfile

L

path

);

//Debug。Log(result);

if

result

!=

0

{

Debug

LogError

LuaDLL

lua_tostring

L

-

1

));

}

luaL_loadfile(IntPtr luaState, string filepath)

第一個引數傳入luaState,關於luaState,第一篇文章講了。

第二個引數傳入檔案路徑

。返回值是數字,

如果返回0代表成功,0以外的代表失敗

。 如果路徑是正確的,沒有什麼好說的。

如果是失敗,lua是不會自己報錯的。

出錯時,

lua會把錯誤資訊壓入棧中

,所以需要呼叫

LuaDLL.lua_tostring(L, -1)

把錯誤資訊拿出來。 當傳入錯誤路徑時,錯誤資訊如下:

【Lua與C#互動②】載入Lua檔案

if

LuaDLL

lua_pcall

L

0

0

0

!=

0

{

Debug

LogError

LuaDLL

lua_tostring

L

-

1

));

}

lua_pcall(IntPtr luaState, int nArgs, int nResults, int errfunc)

這個函式的作用是

執行之前載入的lua檔案

,使用

loadfile後lua虛擬機器並不會執行程式碼

,只會編譯程式碼,所以需要呼叫pcall。 lua_pcall包含了四個引數,分別是

luaState,引數個數,返回值個數,錯誤處理函式在棧中的索引

。本篇案例是最簡單的情況,因為Lua程式碼沒有方法,也就沒有引數個數,沒有返回值,我們也不處理錯誤。所以後面三個引數都是0。關於這個方法的複雜情況,以後會講。

另外,

luaL_loadfile

lua_pcall

兩步可以直接用

luaL_dofile

替代。

LuaDLL

lua_getglobal

L

“a”

);

LuaDLL

lua_getglobal

L

“b”

);

關於lua的棧

lua的棧是用來處理lua和其它語言互動的部分,並不是lua內部跑的程式碼都在這個棧上

。lua內部有自己的記憶體區用來管理lua自身的程式碼。所以即使執行了lua檔案,lua檔案裡面的公共變數也不是在棧上。

lua_getglobal(IntPtr luaState, string name)

lua_getglobal把lua裡的公共變數壓棧,以便C#端能夠呼叫。上面兩行程式碼的意思是把“a”和“b”分別壓棧。

if

LuaDLL

lua_isnumber

L

-

2

==

1

{

Debug

Log

LuaDLL

lua_tonumber

L

,-

2

));

}

if

LuaDLL

lua_isnumber

L

-

1

==

1

{

Debug

Log

LuaDLL

lua_tonumber

L

,-

1

));

}

lua_isnumber(IntPtr luaState, int idx)

最後列印結果,lua_isnumber上篇也講了,不過上篇文章用的是xlua,xlua封裝lua原生api的時候把返回值改成bool了,實際上lua原生api是返回int值。

返回1代表true,返回0代表false

。 注意,當呼叫lua_tonumber時

並不會把返回的值出棧

。如果想把棧頂出棧,需要呼叫

LuaDLL.lua_pop(L,1)

。可以嘗試下面的程式碼: 結果是先列印最後入棧的b的值200,再列印a的值100

if

LuaDLL

lua_isnumber

L

-

1

==

1

{

Debug

Log

LuaDLL

lua_tonumber

L

,-

1

));

}

LuaDLL

lua_pop

L

1

);

if

LuaDLL

lua_isnumber

L

-

1

==

1

{

Debug

Log

LuaDLL

lua_tonumber

L

,-

1

));

}

那麼這次的內容就這些了, github工程地址對應的是

Example/02_LoadFile

資料夾。

系列文章:

【Lua與C#互動①】Lua中的棧_lua_水雞的遊戲開發學習筆記-CSDN部落格

【Lua與C#互動②】載入Lua檔案_lua_水雞的遊戲開發學習筆記-CSDN部落格

【Lua與C#互動③】方法呼叫和錯誤處理函式_水雞的遊戲開發學習筆記-CSDN部落格

qq群:891809847