UniLua純 C# 實(shí)現(xiàn)的 Lua 5.2
UniLua 是一個(gè)純 C# 實(shí)現(xiàn)的 Lua 5.2,側(cè)重于兼容性。
最樸素的從 C# 調(diào)用 lua 的一個(gè)全局函數(shù)的寫法:
Lua.GetGlobal( "foo" ); // 加載 lua 中定義的一個(gè)名叫 foo 的全局函數(shù)到堆棧
Debug.Assert( Lua.IsFunction(-1) ); // 確保加載成功了, 此時(shí)棧頂是函數(shù) foo
Lua.PushString( "test" ); // 將第一個(gè)參數(shù)(字符串 "test")入棧
Lua.PushInteger( 42 ); //將第二個(gè)參數(shù)(整數(shù) 42)入棧
Lua.Call(2, 0); // 調(diào)用函數(shù) foo, 指明有2個(gè)參數(shù),沒有返回值
// 上面的代碼相當(dāng)于 lua 里一個(gè)這樣的調(diào)用 foo("test", 42)
稍微復(fù)雜一點(diǎn)的例子可以參考實(shí)例程序里的一些簡單寫法: 參考這個(gè)文件 Assets/Behaviour/LuaScriptController.cs:
示例代碼:
// 創(chuàng)建 Lua 虛擬機(jī)
var Lua = LuaAPI.NewState();
// 加載基本庫
Lua.L_OpenLibs();
// 加載 Lua 腳本文件
var LuaScriptFile = "framework/main.lua";
var status = Lua.L_DoFile( LuaScriptFile );
// 捕獲錯(cuò)誤
if( status != ThreadStatus.LUA_OK )
{
throw new Exception( Lua.ToString(-1) );
}
// 確保 framework/main.lua 執(zhí)行結(jié)果是一個(gè) Lua Table
if( ! Lua.IsTable(-1) )
{
throw new Exception(
"framework main's return value is not a table" );
}
// 從 framework/main.lua 返回的 table 中讀取 awake 字段指向的函數(shù)
// 并保存到 AwakeRef 中 (可以將 AwakeRef 視為這個(gè)函數(shù)的句柄)
var AwakeRef = StoreMethod( "awake" );
// 不再需要 framework/main.lua 返回的 table 了,將其從棧上彈出
Lua.Pop(1);
//----------------------------------------------------
// 在需要的時(shí)候可以這樣調(diào)用 AwakeRef 指向的 lua 函數(shù)
CallMethod( AwakeRef );
//----------------------------------------------------
// StoreMethod 和 CallMethod 的實(shí)現(xiàn)
private int StoreMethod( string name )
{
Lua.GetField( -1, name );
if( !Lua.IsFunction( -1 ) )
{
throw new Exception( string.Format(
"method {0} not found!", name ) );
}
return Lua.L_Ref( LuaDef.LUA_REGISTRYINDEX );
}
private void CallMethod( int funcRef )
{
Lua.RawGetI( LuaDef.LUA_REGISTRYINDEX, funcRef );
var status = Lua.PCall( 0, 0, 0 );
if( status != ThreadStatus.LUA_OK )
{
Debug.LogError( Lua.ToString(-1) );
}
}
評論
圖片
表情
